summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/db/models/fields/reverse_related.py8
-rw-r--r--tests/admin_filters/tests.py37
-rw-r--r--tests/model_fields/tests.py11
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],
+ )