From dbb0df2a0ec5bee80bee336fc81408efb30b7e47 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Thu, 24 Dec 2015 10:25:59 -0500 Subject: [PATCH] Fixed #25985 -- Updated signature of ModelAdmin.formfield_for_* to make request a positional argument. --- django/contrib/admin/options.py | 10 ++++------ django/contrib/gis/admin/options.py | 5 ++--- docs/topics/db/multi-db.txt | 16 ++++++++-------- tests/admin_ordering/tests.py | 12 ++++++------ 4 files changed, 20 insertions(+), 23 deletions(-) diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 42880aba815..d30fe837568 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -119,15 +119,13 @@ class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)): overrides.update(self.formfield_overrides) self.formfield_overrides = overrides - def formfield_for_dbfield(self, db_field, **kwargs): + def formfield_for_dbfield(self, db_field, request, **kwargs): """ Hook for specifying the form Field instance for a given database Field instance. If kwargs are given, they're passed to the form Field's constructor. """ - request = kwargs.pop("request", None) - # If the field specifies choices, we don't need to look for special # admin widgets - we just need to use a select widget of some kind. if db_field.choices: @@ -177,7 +175,7 @@ class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)): # For any other type of field, just call its formfield() method. return db_field.formfield(**kwargs) - def formfield_for_choice_field(self, db_field, request=None, **kwargs): + def formfield_for_choice_field(self, db_field, request, **kwargs): """ Get a form Field for a database Field that has declared choices. """ @@ -208,7 +206,7 @@ class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)): return db_field.remote_field.model._default_manager.using(db).order_by(*ordering) return None - def formfield_for_foreignkey(self, db_field, request=None, **kwargs): + def formfield_for_foreignkey(self, db_field, request, **kwargs): """ Get a form Field for a ForeignKey. """ @@ -229,7 +227,7 @@ class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)): return db_field.formfield(**kwargs) - def formfield_for_manytomany(self, db_field, request=None, **kwargs): + def formfield_for_manytomany(self, db_field, request, **kwargs): """ Get a form Field for a ManyToManyField. """ diff --git a/django/contrib/gis/admin/options.py b/django/contrib/gis/admin/options.py index ed983a13370..0fe5400c1d0 100644 --- a/django/contrib/gis/admin/options.py +++ b/django/contrib/gis/admin/options.py @@ -52,19 +52,18 @@ class GeoModelAdmin(ModelAdmin): media.add_js(self.extra_js) return media - def formfield_for_dbfield(self, db_field, **kwargs): + def formfield_for_dbfield(self, db_field, request, **kwargs): """ Overloaded from ModelAdmin so that an OpenLayersWidget is used for viewing/editing 2D GeometryFields (OpenLayers 2 does not support 3D editing). """ if isinstance(db_field, models.GeometryField) and db_field.dim < 3: - kwargs.pop('request', None) # Setting the widget with the newly defined widget. kwargs['widget'] = self.get_map_widget(db_field) return db_field.formfield(**kwargs) else: - return super(GeoModelAdmin, self).formfield_for_dbfield(db_field, **kwargs) + return super(GeoModelAdmin, self).formfield_for_dbfield(db_field, request, **kwargs) def get_map_widget(self, db_field): """ diff --git a/docs/topics/db/multi-db.txt b/docs/topics/db/multi-db.txt index bb407205733..f4b63670331 100644 --- a/docs/topics/db/multi-db.txt +++ b/docs/topics/db/multi-db.txt @@ -571,15 +571,15 @@ multiple-database support:: # Tell Django to look for objects on the 'other' database. return super(MultiDBModelAdmin, self).get_queryset(request).using(self.using) - def formfield_for_foreignkey(self, db_field, request=None, **kwargs): + def formfield_for_foreignkey(self, db_field, request, **kwargs): # Tell Django to populate ForeignKey widgets using a query # on the 'other' database. - return super(MultiDBModelAdmin, self).formfield_for_foreignkey(db_field, request=request, using=self.using, **kwargs) + return super(MultiDBModelAdmin, self).formfield_for_foreignkey(db_field, request, using=self.using, **kwargs) - def formfield_for_manytomany(self, db_field, request=None, **kwargs): + def formfield_for_manytomany(self, db_field, request, **kwargs): # Tell Django to populate ManyToMany widgets using a query # on the 'other' database. - return super(MultiDBModelAdmin, self).formfield_for_manytomany(db_field, request=request, using=self.using, **kwargs) + return super(MultiDBModelAdmin, self).formfield_for_manytomany(db_field, request, using=self.using, **kwargs) The implementation provided here implements a multi-database strategy where all objects of a given type are stored on a specific database @@ -596,15 +596,15 @@ Inlines can be handled in a similar fashion. They require three customized metho # Tell Django to look for inline objects on the 'other' database. return super(MultiDBTabularInline, self).get_queryset(request).using(self.using) - def formfield_for_foreignkey(self, db_field, request=None, **kwargs): + def formfield_for_foreignkey(self, db_field, request, **kwargs): # Tell Django to populate ForeignKey widgets using a query # on the 'other' database. - return super(MultiDBTabularInline, self).formfield_for_foreignkey(db_field, request=request, using=self.using, **kwargs) + return super(MultiDBTabularInline, self).formfield_for_foreignkey(db_field, request, using=self.using, **kwargs) - def formfield_for_manytomany(self, db_field, request=None, **kwargs): + def formfield_for_manytomany(self, db_field, request, **kwargs): # Tell Django to populate ManyToMany widgets using a query # on the 'other' database. - return super(MultiDBTabularInline, self).formfield_for_manytomany(db_field, request=request, using=self.using, **kwargs) + return super(MultiDBTabularInline, self).formfield_for_manytomany(db_field, request, using=self.using, **kwargs) Once you've written your model admin definitions, they can be registered with any ``Admin`` instance:: diff --git a/tests/admin_ordering/tests.py b/tests/admin_ordering/tests.py index e23195d8d78..6e19accc211 100644 --- a/tests/admin_ordering/tests.py +++ b/tests/admin_ordering/tests.py @@ -129,8 +129,8 @@ class TestRelatedFieldsAdminOrdering(TestCase): site.unregister(Band) def check_ordering_of_field_choices(self, correct_ordering): - fk_field = site._registry[Song].formfield_for_foreignkey(Song.band.field) - m2m_field = site._registry[Song].formfield_for_manytomany(Song.other_interpreters.field) + fk_field = site._registry[Song].formfield_for_foreignkey(Song.band.field, request=None) + m2m_field = site._registry[Song].formfield_for_manytomany(Song.other_interpreters.field, request=None) self.assertListEqual(list(fk_field.queryset), correct_ordering) self.assertListEqual(list(m2m_field.queryset), correct_ordering) @@ -159,15 +159,15 @@ class TestRelatedFieldsAdminOrdering(TestCase): """Test that custom queryset has still precedence (#21405)""" class SongAdmin(admin.ModelAdmin): # Exclude one of the two Bands from the querysets - def formfield_for_foreignkey(self, db_field, **kwargs): + def formfield_for_foreignkey(self, db_field, request, **kwargs): if db_field.name == 'band': kwargs["queryset"] = Band.objects.filter(rank__gt=2) - return super(SongAdmin, self).formfield_for_foreignkey(db_field, **kwargs) + return super(SongAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs) - def formfield_for_manytomany(self, db_field, **kwargs): + def formfield_for_manytomany(self, db_field, request, **kwargs): if db_field.name == 'other_interpreters': kwargs["queryset"] = Band.objects.filter(rank__gt=2) - return super(SongAdmin, self).formfield_for_foreignkey(db_field, **kwargs) + return super(SongAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs) class StaticOrderingBandAdmin(admin.ModelAdmin): ordering = ('rank',)