summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2020-09-24 09:45:51 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-09-25 10:10:26 +0200
commitb7df7de44f03b569d223ed6f2c6698b7f039d38f (patch)
tree7a334960518b8520bfca89f31c0df29ca2db13e0
parent986cd28f95c77bd14907726caa0f8b0734a4e581 (diff)
[3.1.x] Fixed #32038 -- Fixed EmptyFieldListFilter crash with GenericRelation.
Thanks Javier Matos Odut for the report. Backport of e4ab44a4b2ef70be09c35c9197a19fd2e993b4d6 from master
-rw-r--r--django/contrib/contenttypes/fields.py4
-rw-r--r--docs/releases/3.1.2.txt3
-rw-r--r--tests/admin_filters/tests.py26
3 files changed, 33 insertions, 0 deletions
diff --git a/django/contrib/contenttypes/fields.py b/django/contrib/contenttypes/fields.py
index 3282fd6d4b..c0d085ffc2 100644
--- a/django/contrib/contenttypes/fields.py
+++ b/django/contrib/contenttypes/fields.py
@@ -277,6 +277,7 @@ class GenericRelation(ForeignObject):
# Field flags
auto_created = False
+ empty_strings_allowed = False
many_to_many = False
many_to_one = False
@@ -295,6 +296,9 @@ class GenericRelation(ForeignObject):
limit_choices_to=limit_choices_to,
)
+ # Reverse relations are always nullable (Django can't enforce that a
+ # foreign key on the related model points to this model).
+ kwargs['null'] = True
kwargs['blank'] = True
kwargs['on_delete'] = models.CASCADE
kwargs['editable'] = False
diff --git a/docs/releases/3.1.2.txt b/docs/releases/3.1.2.txt
index 90ce6af97f..598bd2a754 100644
--- a/docs/releases/3.1.2.txt
+++ b/docs/releases/3.1.2.txt
@@ -23,3 +23,6 @@ Bugfixes
* Fixed a bug in Django 3.1 where a test database was not synced during
creation when using the :setting:`MIGRATE <TEST_MIGRATE>` test database
setting (:ticket:`32012`).
+
+* Fixed a ``django.contrib.admin.EmptyFieldListFilter`` crash when using on a
+ ``GenericRelation`` (:ticket:`32038`).
diff --git a/tests/admin_filters/tests.py b/tests/admin_filters/tests.py
index 16a7ce495c..cec55f63eb 100644
--- a/tests/admin_filters/tests.py
+++ b/tests/admin_filters/tests.py
@@ -1477,6 +1477,32 @@ class ListFiltersTests(TestCase):
queryset = changelist.get_queryset(request)
self.assertCountEqual(queryset, expected_result)
+ def test_emptylistfieldfilter_genericrelation(self):
+ class BookmarkGenericRelation(ModelAdmin):
+ list_filter = (
+ ('tags', EmptyFieldListFilter),
+ )
+
+ modeladmin = BookmarkGenericRelation(Bookmark, site)
+
+ django_bookmark = Bookmark.objects.create(url='https://www.djangoproject.com/')
+ python_bookmark = Bookmark.objects.create(url='https://www.python.org/')
+ none_tags = Bookmark.objects.create(url='https://www.kernel.org/')
+ TaggedItem.objects.create(content_object=django_bookmark, tag='python')
+ TaggedItem.objects.create(content_object=python_bookmark, tag='python')
+
+ tests = [
+ ({'tags__isempty': '1'}, [none_tags]),
+ ({'tags__isempty': '0'}, [django_bookmark, python_bookmark]),
+ ]
+ for query_string, expected_result in tests:
+ with self.subTest(query_string=query_string):
+ request = self.request_factory.get('/', query_string)
+ request.user = self.alfred
+ changelist = modeladmin.get_changelist_instance(request)
+ queryset = changelist.get_queryset(request)
+ self.assertCountEqual(queryset, expected_result)
+
def test_emptylistfieldfilter_choices(self):
modeladmin = BookAdminWithEmptyFieldListFilter(Book, site)
request = self.request_factory.get('/')