Fixed #25606 -- Added support for "__" lookup in RelatedOnlyFieldList

This commit is contained in:
Andrey Kuzmin 2015-10-25 22:15:37 +02:00 committed by Tim Graham
parent 7624fdb9f8
commit 815f4d206d
3 changed files with 30 additions and 3 deletions

View File

@ -166,9 +166,9 @@ class RelatedFieldListFilter(FieldListFilter):
self.lookup_kwarg_isnull = '%s__isnull' % field_path self.lookup_kwarg_isnull = '%s__isnull' % field_path
self.lookup_val = request.GET.get(self.lookup_kwarg) self.lookup_val = request.GET.get(self.lookup_kwarg)
self.lookup_val_isnull = request.GET.get(self.lookup_kwarg_isnull) 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__( super(RelatedFieldListFilter, self).__init__(
field, request, params, model, model_admin, field_path) field, request, params, model, model_admin, field_path)
self.lookup_choices = self.field_choices(field, request, model_admin)
if hasattr(field, 'verbose_name'): if hasattr(field, 'verbose_name'):
self.lookup_title = field.verbose_name self.lookup_title = field.verbose_name
else: else:
@ -412,5 +412,5 @@ FieldListFilter.register(lambda f: True, AllValuesFieldListFilter)
class RelatedOnlyFieldListFilter(RelatedFieldListFilter): class RelatedOnlyFieldListFilter(RelatedFieldListFilter):
def field_choices(self, field, request, model_admin): 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))} 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=limit_choices_to) return field.get_choices(include_blank=False, limit_choices_to={'pk__in': pk_qs})

View File

@ -26,6 +26,12 @@ class Book(models.Model):
related_name='books_contributed', related_name='books_contributed',
blank=True, blank=True,
) )
employee = models.ForeignKey(
'Employee',
models.SET_NULL,
verbose_name='Employee',
blank=True, null=True,
)
is_best_seller = models.NullBooleanField(default=0) is_best_seller = models.NullBooleanField(default=0)
date_registered = models.DateField(null=True) date_registered = models.DateField(null=True)
# This field name is intentionally 2 characters long (#16080). # This field name is intentionally 2 characters long (#16080).

View File

@ -169,6 +169,7 @@ class BookAdminRelatedOnlyFilter(ModelAdmin):
'year', 'is_best_seller', 'date_registered', 'no', 'year', 'is_best_seller', 'date_registered', 'no',
('author', RelatedOnlyFieldListFilter), ('author', RelatedOnlyFieldListFilter),
('contributors', RelatedOnlyFieldListFilter), ('contributors', RelatedOnlyFieldListFilter),
('employee__department', RelatedOnlyFieldListFilter),
) )
ordering = ('-id',) ordering = ('-id',)
@ -580,6 +581,26 @@ class ListFiltersTests(TestCase):
expected = [(self.alfred.pk, 'alfred'), (self.bob.pk, 'bob')] expected = [(self.alfred.pk, 'alfred'), (self.bob.pk, 'bob')]
self.assertEqual(sorted(filterspec.lookup_choices), sorted(expected)) 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): def test_relatedonlyfieldlistfilter_manytomany(self):
modeladmin = BookAdminRelatedOnlyFilter(Book, site) modeladmin = BookAdminRelatedOnlyFilter(Book, site)