Created
January 29, 2010 22:34
-
-
Save mrts/290224 to your computer and use it in GitHub Desktop.
Use raw_id_fields widget in custom ModelForm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
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 argumentadmin.site
- second, the
ForeignKeyRawIdWidget(...)
uses the_default_manager
only for rendering the current value, not for limiting the model queryset - third, the
ForeignKeyRawIdWidget(...)
has anif ...
block to check whether.rel.to
is registered within the passedadmin.site
(which is not the case, because we instantiate.rel.to
to the classToWrapper
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
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.
For Django>=2.0 you should use remote_field
instead of rel
.
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
Thanks a lot!