Commit 9cbcd06b authored by Claude Paroz's avatar Claude Paroz
Browse files

[1.6.x] Fixed #21405 -- Prevented queryset overwrite in BaseModelAdmin

Thanks guido@20tab.com for the report and Tim Graham for the
analyze.
Backport of 1718b525 from master.
parent 5730bf28
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -209,6 +209,7 @@ class BaseModelAdmin(six.with_metaclass(RenameBaseModelAdminMethods)):
            })
            kwargs['empty_label'] = _('None') if db_field.blank else None

        if not 'queryset' in kwargs:
            queryset = self.get_field_queryset(db, db_field, request)
            if queryset is not None:
                kwargs['queryset'] = queryset
@@ -232,6 +233,7 @@ class BaseModelAdmin(six.with_metaclass(RenameBaseModelAdminMethods)):
        elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
            kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))

        if not 'queryset' in kwargs:
            queryset = self.get_field_queryset(db, db_field, request)
            if queryset is not None:
                kwargs['queryset'] = queryset
+2 −0
Original line number Diff line number Diff line
@@ -28,3 +28,5 @@ Bug fixes
  non related to file extensions (#21457).
* Fixed display of inline instances in formsets when parent has 0 for primary
  key (#21472).
* Fixed a regression where custom querysets for foreign keys were overwritten
  if ``ModelAdmin`` had ordering set (#21405).
+22 −0
Original line number Diff line number Diff line
@@ -148,6 +148,28 @@ class TestRelatedFieldsAdminOrdering(TestCase):
        # should be ordered by rank (defined by the ModelAdmin)
        self.check_ordering_of_field_choices([self.b1, self.b2])

    def test_custom_queryset_still_wins(self):
        """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):
                if db_field.name == 'band':
                    kwargs["queryset"] = Band.objects.filter(rank__gt=2)
                return super(SongAdmin, self).formfield_for_foreignkey(db_field, **kwargs)
            def formfield_for_manytomany(self, db_field, **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)

        class StaticOrderingBandAdmin(admin.ModelAdmin):
            ordering = ('rank',)

        admin.site.unregister(Song)
        admin.site.register(Song, SongAdmin)
        admin.site.register(Band, StaticOrderingBandAdmin)

        self.check_ordering_of_field_choices([self.b2])

    def tearDown(self):
        admin.site.unregister(Song)
        if Band in admin.site._registry: