Loading django/contrib/admin/filters.py +3 −3 Original line number Diff line number Diff line Loading @@ -166,9 +166,9 @@ class RelatedFieldListFilter(FieldListFilter): self.lookup_kwarg_isnull = '%s__isnull' % field_path self.lookup_val = request.GET.get(self.lookup_kwarg) self.lookup_val_isnull = request.GET.get(self.lookup_kwarg_isnull) self.lookup_choices = self.field_choices(field, request, model_admin) super(RelatedFieldListFilter, self).__init__( field, request, params, model, model_admin, field_path) self.lookup_choices = self.field_choices(field, request, model_admin) if hasattr(field, 'verbose_name'): self.lookup_title = field.verbose_name else: Loading Loading @@ -412,5 +412,5 @@ FieldListFilter.register(lambda f: True, AllValuesFieldListFilter) class RelatedOnlyFieldListFilter(RelatedFieldListFilter): def field_choices(self, field, request, model_admin): limit_choices_to = {'pk__in': set(model_admin.get_queryset(request).values_list(field.name, flat=True))} return field.get_choices(include_blank=False, limit_choices_to=limit_choices_to) pk_qs = model_admin.get_queryset(request).distinct().values_list('%s__pk' % self.field_path, flat=True) return field.get_choices(include_blank=False, limit_choices_to={'pk__in': pk_qs}) tests/admin_filters/models.py +6 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,12 @@ class Book(models.Model): related_name='books_contributed', blank=True, ) employee = models.ForeignKey( 'Employee', models.SET_NULL, verbose_name='Employee', blank=True, null=True, ) is_best_seller = models.NullBooleanField(default=0) date_registered = models.DateField(null=True) # This field name is intentionally 2 characters long (#16080). Loading tests/admin_filters/tests.py +21 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,7 @@ class BookAdminRelatedOnlyFilter(ModelAdmin): 'year', 'is_best_seller', 'date_registered', 'no', ('author', RelatedOnlyFieldListFilter), ('contributors', RelatedOnlyFieldListFilter), ('employee__department', RelatedOnlyFieldListFilter), ) ordering = ('-id',) Loading Loading @@ -580,6 +581,26 @@ class ListFiltersTests(TestCase): expected = [(self.alfred.pk, 'alfred'), (self.bob.pk, 'bob')] self.assertEqual(sorted(filterspec.lookup_choices), sorted(expected)) def test_relatedonlyfieldlistfilter_underscorelookup_foreignkey(self): Department.objects.create(code='TEST', description='Testing') self.djangonaut_book.employee = self.john self.djangonaut_book.save() self.bio_book.employee = self.jack self.bio_book.save() modeladmin = BookAdminRelatedOnlyFilter(Book, site) request = self.request_factory.get('/') changelist = self.get_changelist(request, Book, modeladmin) # Only actual departments should be present in employee__department's # list filter. filterspec = changelist.get_filters(request)[0][6] expected = [ (self.dev.code, str(self.dev)), (self.design.code, str(self.design)), ] self.assertEqual(sorted(filterspec.lookup_choices), sorted(expected)) def test_relatedonlyfieldlistfilter_manytomany(self): modeladmin = BookAdminRelatedOnlyFilter(Book, site) Loading Loading
django/contrib/admin/filters.py +3 −3 Original line number Diff line number Diff line Loading @@ -166,9 +166,9 @@ class RelatedFieldListFilter(FieldListFilter): self.lookup_kwarg_isnull = '%s__isnull' % field_path self.lookup_val = request.GET.get(self.lookup_kwarg) self.lookup_val_isnull = request.GET.get(self.lookup_kwarg_isnull) self.lookup_choices = self.field_choices(field, request, model_admin) super(RelatedFieldListFilter, self).__init__( field, request, params, model, model_admin, field_path) self.lookup_choices = self.field_choices(field, request, model_admin) if hasattr(field, 'verbose_name'): self.lookup_title = field.verbose_name else: Loading Loading @@ -412,5 +412,5 @@ FieldListFilter.register(lambda f: True, AllValuesFieldListFilter) class RelatedOnlyFieldListFilter(RelatedFieldListFilter): def field_choices(self, field, request, model_admin): limit_choices_to = {'pk__in': set(model_admin.get_queryset(request).values_list(field.name, flat=True))} return field.get_choices(include_blank=False, limit_choices_to=limit_choices_to) pk_qs = model_admin.get_queryset(request).distinct().values_list('%s__pk' % self.field_path, flat=True) return field.get_choices(include_blank=False, limit_choices_to={'pk__in': pk_qs})
tests/admin_filters/models.py +6 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,12 @@ class Book(models.Model): related_name='books_contributed', blank=True, ) employee = models.ForeignKey( 'Employee', models.SET_NULL, verbose_name='Employee', blank=True, null=True, ) is_best_seller = models.NullBooleanField(default=0) date_registered = models.DateField(null=True) # This field name is intentionally 2 characters long (#16080). Loading
tests/admin_filters/tests.py +21 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,7 @@ class BookAdminRelatedOnlyFilter(ModelAdmin): 'year', 'is_best_seller', 'date_registered', 'no', ('author', RelatedOnlyFieldListFilter), ('contributors', RelatedOnlyFieldListFilter), ('employee__department', RelatedOnlyFieldListFilter), ) ordering = ('-id',) Loading Loading @@ -580,6 +581,26 @@ class ListFiltersTests(TestCase): expected = [(self.alfred.pk, 'alfred'), (self.bob.pk, 'bob')] self.assertEqual(sorted(filterspec.lookup_choices), sorted(expected)) def test_relatedonlyfieldlistfilter_underscorelookup_foreignkey(self): Department.objects.create(code='TEST', description='Testing') self.djangonaut_book.employee = self.john self.djangonaut_book.save() self.bio_book.employee = self.jack self.bio_book.save() modeladmin = BookAdminRelatedOnlyFilter(Book, site) request = self.request_factory.get('/') changelist = self.get_changelist(request, Book, modeladmin) # Only actual departments should be present in employee__department's # list filter. filterspec = changelist.get_filters(request)[0][6] expected = [ (self.dev.code, str(self.dev)), (self.design.code, str(self.design)), ] self.assertEqual(sorted(filterspec.lookup_choices), sorted(expected)) def test_relatedonlyfieldlistfilter_manytomany(self): modeladmin = BookAdminRelatedOnlyFilter(Book, site) Loading