diff --git a/AUTHORS b/AUTHORS index 70f402588f3d..3edfbecf2ab4 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1151,6 +1151,7 @@ answer newbie questions, and generally made Django that much better: Zeynel Özdemir Zlatko Mašek zriv + Zubair Hassan A big THANK YOU goes to: diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py index a6adafabbefb..aafbae9d90cb 100644 --- a/django/contrib/admin/templatetags/admin_list.py +++ b/django/contrib/admin/templatetags/admin_list.py @@ -16,7 +16,7 @@ PAGE_VAR, SEARCH_VAR, ) -from django.core.exceptions import ObjectDoesNotExist +from django.core.exceptions import FieldDoesNotExist, ObjectDoesNotExist from django.db import models from django.db.models.constants import LOOKUP_SEP from django.template import Library @@ -226,6 +226,12 @@ def link_in_col(is_first, field_name, cl): empty_value_display = getattr( attr, "empty_value_display", empty_value_display ) + # Find boolean fields on relations. + if f is None and isinstance(field_name, str) and LOOKUP_SEP in field_name: + try: + f = get_fields_from_path(cl.model, field_name)[-1] + except FieldDoesNotExist: + pass # e.g. __str__ if f is None or f.auto_created: if field_name == "action_checkbox": row_classes = ["action-checkbox"] diff --git a/django/contrib/admin/utils.py b/django/contrib/admin/utils.py index 746537e9c5f8..34f53a4df2c2 100644 --- a/django/contrib/admin/utils.py +++ b/django/contrib/admin/utils.py @@ -314,9 +314,6 @@ def lookup_field(name, obj, model_admin=None): attr = getattr(attr, part, sentinel) if attr is sentinel: return None, None, None - # The final field is needed for displaying boolean icons. - if LOOKUP_SEP in name: - f = get_fields_from_path(opts.model, name)[-1] value = attr if hasattr(model_admin, "model") and hasattr(model_admin.model, name): attr = getattr(model_admin.model, name) diff --git a/docs/intro/reusable-apps.txt b/docs/intro/reusable-apps.txt index bb33dc01973c..41122dff9acb 100644 --- a/docs/intro/reusable-apps.txt +++ b/docs/intro/reusable-apps.txt @@ -211,7 +211,7 @@ this. For a small app like polls, this process isn't too difficult. :caption: ``django-polls/pyproject.toml`` [build-system] - requires = ["setuptools>=77.0.3"] + requires = ["setuptools>83"] build-backend = "setuptools.build_meta" [project] diff --git a/docs/releases/5.2.17.txt b/docs/releases/5.2.17.txt new file mode 100644 index 000000000000..769513899ded --- /dev/null +++ b/docs/releases/5.2.17.txt @@ -0,0 +1,9 @@ +=========================== +Django 5.2.17 release notes +=========================== + +*August 4, 2026* + +Django 5.2.17 fixes one security issue with severity "high", two security +issues with severity "moderate", and one security issue with severity "low" in +5.2.16. diff --git a/docs/releases/6.0.8.txt b/docs/releases/6.0.8.txt index 4a6d167e1291..4f05b218da02 100644 --- a/docs/releases/6.0.8.txt +++ b/docs/releases/6.0.8.txt @@ -2,9 +2,11 @@ Django 6.0.8 release notes ========================== -*Expected August 4, 2026* +*August 4, 2026* -Django 6.0.8 fixes several bugs in 6.0.7. +Django 6.0.8 fixes one security issue with severity "high", two security issues +with severity "moderate", one security issue with severity "low", and several +bugs in 6.0.7. Bugfixes ======== diff --git a/docs/releases/index.txt b/docs/releases/index.txt index 484f40f0e2d9..43aebc7ea38e 100644 --- a/docs/releases/index.txt +++ b/docs/releases/index.txt @@ -54,6 +54,7 @@ versions of the documentation contain the release notes for any later releases. .. toctree:: :maxdepth: 1 + 5.2.17 5.2.16 5.2.15 5.2.14 diff --git a/pyproject.toml b/pyproject.toml index 45dd9c2a271c..cb9d0e6b8d31 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools>=77.0.3"] +requires = ["setuptools>=83"] build-backend = "setuptools.build_meta" [project] diff --git a/tests/admin_utils/models.py b/tests/admin_utils/models.py index 55810f0b50a8..59b4eab5c6af 100644 --- a/tests/admin_utils/models.py +++ b/tests/admin_utils/models.py @@ -5,6 +5,9 @@ class Site(models.Model): domain = models.CharField(max_length=100) + parent = models.ForeignKey( + "self", models.CASCADE, related_name="children", blank=True, null=True + ) def __str__(self): return self.domain diff --git a/tests/admin_utils/tests.py b/tests/admin_utils/tests.py index 15b09ca812ac..a04393933681 100644 --- a/tests/admin_utils/tests.py +++ b/tests/admin_utils/tests.py @@ -164,6 +164,7 @@ def simple_function(obj): ("test_from_model", article.test_from_model()), ("non_field", INSTANCE_ATTRIBUTE), ("site__domain", SITE_NAME), + ("site__parent", None), ) mock_admin = MockModelAdmin()