Skip to content

Instantly share code, notes, and snippets.

@mrts
Created January 29, 2010 22:34
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrts/290224 to your computer and use it in GitHub Desktop.
Save mrts/290224 to your computer and use it in GitHub Desktop.
Use raw_id_fields widget in custom ModelForm
from django.contrib.admin import widgets
from django import forms
from django.contrib import admin
# create wrappers for overriding the queryset
class ToWrapper(object):
def __init__(self, to, manager):
self.to = to
self._default_manager = manager
def __getattr__(self, name):
return getattr(self.to, name)
class RelWrapper(object):
def __init__(self, rel, manager):
self.rel = rel
self.to = ToWrapper(rel.to, manager)
def __getattr__(self, name):
return getattr(self.rel, name)
class FooForm(forms.ModelForm):
bar = forms.ModelChoiceField(queryset=Bar.all_objects,
label=_("Bar"),
widget=widgets.ForeignKeyRawIdWidget(
RelWrapper(Foo._meta.get_field('bar').rel,
Bar.all_objects)))
class Meta:
model = Foo
class FooAdmin(admin.ModelAdmin):
form = FooForm
@gsvster
Copy link

gsvster commented Jan 5, 2015

Thanks a lot!

@fspegni
Copy link

fspegni commented Jun 9, 2015

This is a very nice piece of code, but it does not work on Django 1.5. With which versions of Django does it work?

In Django 1.5 I see a few problems:

  • first, the widget=widgets.ForeignKeyRawIdWidget(...) should receive a reference to a third argument admin.site
  • second, the ForeignKeyRawIdWidget(...) uses the _default_manager only for rendering the current value, not for limiting the model queryset
  • third, the ForeignKeyRawIdWidget(...) has an if ... block to check whether .rel.to is registered within the passed admin.site (which is not the case, because we instantiate .rel.to to the class ToWrapper

It would be great if it were possible to amend the code for Django 1.5, but I couldn't find an acceptable solution, so far

@Madalosso
Copy link

I'm using Django 1.6 and the follow seems to work fine:

class MyCustomForm(ModelForm):
    class Meta:
        model = MyModel
        widgets = {
            'field': ForeignKeyRawIdWidget(MyModel._meta.get_field("field_to_rel").rel, admin.site),
        }

And my ModelAdmin get_form returns MyCustomForm.

@malekzahedi
Copy link

malekzahedi commented Jun 11, 2022

For Django>=2.0 you should use remote_field instead of rel.

@khieu
Copy link

khieu commented Aug 2, 2023

Since Django 1.5 +, the ForeignKeyRawIdWidget require a site variable, which site should I pass to this object (foo or bar) and do you know if it's possible to use ForeignKeyRawIdWidget in a regular forms.Form?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment