diff options
-rw-r--r-- | django/db/models/fields/reverse_related.py | 8 | ||||
-rw-r--r-- | tests/admin_filters/tests.py | 37 | ||||
-rw-r--r-- | tests/model_fields/tests.py | 11 |
3 files changed, 54 insertions, 2 deletions
diff --git a/django/db/models/fields/reverse_related.py b/django/db/models/fields/reverse_related.py index 700410a086..8f0c95962d 100644 --- a/django/db/models/fields/reverse_related.py +++ b/django/db/models/fields/reverse_related.py @@ -114,7 +114,10 @@ class ForeignObjectRel(FieldCacheMixin): self.related_model._meta.model_name, ) - def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH, ordering=()): + def get_choices( + self, include_blank=True, blank_choice=BLANK_CHOICE_DASH, + limit_choices_to=None, ordering=(), + ): """ Return choices with a default blank choices included, for use as <select> choices for this field. @@ -122,7 +125,8 @@ class ForeignObjectRel(FieldCacheMixin): Analog of django.db.models.fields.Field.get_choices(), provided initially for utilization by RelatedFieldListFilter. """ - qs = self.related_model._default_manager.all() + limit_choices_to = limit_choices_to or self.limit_choices_to + qs = self.related_model._default_manager.complex_filter(limit_choices_to) if ordering: qs = qs.order_by(*ordering) return (blank_choice if include_blank else []) + [ diff --git a/tests/admin_filters/tests.py b/tests/admin_filters/tests.py index 4e6f1f4732..ce659f937f 100644 --- a/tests/admin_filters/tests.py +++ b/tests/admin_filters/tests.py @@ -741,6 +741,43 @@ class ListFiltersTests(TestCase): expected = [(self.alfred.pk, 'alfred'), (self.bob.pk, 'bob')] self.assertEqual(sorted(filterspec.lookup_choices), sorted(expected)) + def test_relatedonlyfieldlistfilter_foreignkey_reverse_relationships(self): + class EmployeeAdminReverseRelationship(ModelAdmin): + list_filter = ( + ('book', RelatedOnlyFieldListFilter), + ) + + self.djangonaut_book.employee = self.john + self.djangonaut_book.save() + self.django_book.employee = self.jack + self.django_book.save() + + modeladmin = EmployeeAdminReverseRelationship(Employee, site) + request = self.request_factory.get('/') + request.user = self.alfred + changelist = modeladmin.get_changelist_instance(request) + filterspec = changelist.get_filters(request)[0][0] + self.assertEqual(filterspec.lookup_choices, [ + (self.djangonaut_book.pk, 'Djangonaut: an art of living'), + (self.django_book.pk, 'The Django Book'), + ]) + + def test_relatedonlyfieldlistfilter_manytomany_reverse_relationships(self): + class UserAdminReverseRelationship(ModelAdmin): + list_filter = ( + ('books_contributed', RelatedOnlyFieldListFilter), + ) + + modeladmin = UserAdminReverseRelationship(User, site) + request = self.request_factory.get('/') + request.user = self.alfred + changelist = modeladmin.get_changelist_instance(request) + filterspec = changelist.get_filters(request)[0][0] + self.assertEqual( + filterspec.lookup_choices, + [(self.guitar_book.pk, 'Guitar for dummies')], + ) + def test_relatedonlyfieldlistfilter_foreignkey_ordering(self): """RelatedOnlyFieldListFilter ordering respects ModelAdmin.ordering.""" class EmployeeAdminWithOrdering(ModelAdmin): diff --git a/tests/model_fields/tests.py b/tests/model_fields/tests.py index 206ac8c84c..0d6e930b06 100644 --- a/tests/model_fields/tests.py +++ b/tests/model_fields/tests.py @@ -289,3 +289,14 @@ class GetChoicesLimitChoicesToTests(TestCase): self.field.get_choices(include_blank=False, limit_choices_to={}), [self.foo1, self.foo2], ) + + def test_get_choices_reverse_related_field(self): + field = self.field.remote_field + self.assertChoicesEqual( + field.get_choices(include_blank=False, limit_choices_to={'b': 'b'}), + [self.bar1], + ) + self.assertChoicesEqual( + field.get_choices(include_blank=False, limit_choices_to={}), + [self.bar1, self.bar2], + ) |