summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2023-12-27 20:36:22 +0100
committerGitHub <noreply@github.com>2023-12-27 20:36:22 +0100
commit751d732a3815a68bdb5b7aceda0e7d5981362c4a (patch)
treee1821add39f9cf170c530db29b3de0a28b8cf475
parent21b0b23a67ee1aa1a35f7f64cd8fe997e4de89d7 (diff)
Fixed #35056 -- Fixed system check crash on reverse m2m relations with related_name in ModelAdmin.filter_horizontal/vertical.
Thanks Thomas Feldmann for the report. Regression in 107865780aa44914e21d27fdf4ca269bc61c7f01.
-rw-r--r--django/contrib/admin/checks.py2
-rw-r--r--docs/releases/5.0.1.txt4
-rw-r--r--tests/modeladmin/test_checks.py36
3 files changed, 41 insertions, 1 deletions
diff --git a/django/contrib/admin/checks.py b/django/contrib/admin/checks.py
index 1665023434..aa43718cd6 100644
--- a/django/contrib/admin/checks.py
+++ b/django/contrib/admin/checks.py
@@ -532,7 +532,7 @@ class BaseModelAdminChecks:
field=field_name, option=label, obj=obj, id="admin.E019"
)
else:
- if not field.many_to_many:
+ if not field.many_to_many or isinstance(field, models.ManyToManyRel):
return must_be(
"a many-to-many field", option=label, obj=obj, id="admin.E020"
)
diff --git a/docs/releases/5.0.1.txt b/docs/releases/5.0.1.txt
index 15b735b42e..4344b0d181 100644
--- a/docs/releases/5.0.1.txt
+++ b/docs/releases/5.0.1.txt
@@ -32,3 +32,7 @@ Bugfixes
* Fixed a regression in Django 5.0 where querysets referenced incorrect field
names from ``FilteredRelation()`` (:ticket:`35050`).
+
+* Fixed a regression in Django 5.0 that caused a system check crash when
+ ``ModelAdmin.filter_horizontal`` or ``filter_vertical`` contained a reverse
+ many-to-many relation with ``related_name`` (:ticket:`35056`).
diff --git a/tests/modeladmin/test_checks.py b/tests/modeladmin/test_checks.py
index 47b1b40ed7..73777f05ab 100644
--- a/tests/modeladmin/test_checks.py
+++ b/tests/modeladmin/test_checks.py
@@ -323,6 +323,24 @@ class FilterVerticalCheckTests(CheckTestCase):
)
@isolate_apps("modeladmin")
+ def test_invalid_reverse_m2m_field_with_related_name(self):
+ class Contact(Model):
+ pass
+
+ class Customer(Model):
+ contacts = ManyToManyField("Contact", related_name="customers")
+
+ class TestModelAdmin(ModelAdmin):
+ filter_vertical = ["customers"]
+
+ self.assertIsInvalid(
+ TestModelAdmin,
+ Contact,
+ "The value of 'filter_vertical[0]' must be a many-to-many field.",
+ "admin.E020",
+ )
+
+ @isolate_apps("modeladmin")
def test_invalid_m2m_field_with_through(self):
class Artist(Model):
bands = ManyToManyField("Band", through="BandArtist")
@@ -385,6 +403,24 @@ class FilterHorizontalCheckTests(CheckTestCase):
)
@isolate_apps("modeladmin")
+ def test_invalid_reverse_m2m_field_with_related_name(self):
+ class Contact(Model):
+ pass
+
+ class Customer(Model):
+ contacts = ManyToManyField("Contact", related_name="customers")
+
+ class TestModelAdmin(ModelAdmin):
+ filter_horizontal = ["customers"]
+
+ self.assertIsInvalid(
+ TestModelAdmin,
+ Contact,
+ "The value of 'filter_horizontal[0]' must be a many-to-many field.",
+ "admin.E020",
+ )
+
+ @isolate_apps("modeladmin")
def test_invalid_m2m_field_with_through(self):
class Artist(Model):
bands = ManyToManyField("Band", through="BandArtist")