Fixed #25606 -- Added support for "__" lookup in RelatedOnlyFieldList
This commit is contained in:
parent
7624fdb9f8
commit
815f4d206d
|
@ -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})
|
||||||
|
|
|
@ -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).
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue