1
0
mirror of https://github.com/django/django.git synced 2025-01-03 06:55:47 +00:00

Fixed #35628 -- Allowed compatible GeneratedFields for ModelAdmin.date_hierarchy.

This commit is contained in:
John Parton 2024-07-24 13:53:06 -05:00 committed by Sarah Boyce
parent 90adba85b2
commit 7f8d839722
3 changed files with 58 additions and 3 deletions

View File

@ -1184,7 +1184,7 @@ class ModelAdminChecks(BaseModelAdminChecks):
) )
] ]
else: else:
if not isinstance(field, (models.DateField, models.DateTimeField)): if field.get_internal_type() not in {"DateField", "DateTimeField"}:
return must_be( return must_be(
"a DateField or DateTimeField", "a DateField or DateTimeField",
option="date_hierarchy", option="date_hierarchy",

View File

@ -24,3 +24,7 @@ Bugfixes
* Fixed a regression in Django 5.0.7 that caused a crash in * Fixed a regression in Django 5.0.7 that caused a crash in
``LocaleMiddleware`` when processing a language code over 500 characters ``LocaleMiddleware`` when processing a language code over 500 characters
(:ticket:`35627`). (:ticket:`35627`).
* Fixed a bug in Django 5.0 that caused a system check crash when
``ModelAdmin.date_hierarchy`` was a ``GeneratedField`` with an
``output_field`` of ``DateField`` or ``DateTimeField`` (:ticket:`35628`).

View File

@ -4,16 +4,17 @@ from django.contrib.admin import BooleanFieldListFilter, SimpleListFilter
from django.contrib.admin.options import VERTICAL, ModelAdmin, TabularInline from django.contrib.admin.options import VERTICAL, ModelAdmin, TabularInline
from django.contrib.admin.sites import AdminSite from django.contrib.admin.sites import AdminSite
from django.core.checks import Error from django.core.checks import Error
from django.db import models
from django.db.models import CASCADE, F, Field, ForeignKey, ManyToManyField, Model from django.db.models import CASCADE, F, Field, ForeignKey, ManyToManyField, Model
from django.db.models.functions import Upper from django.db.models.functions import Upper
from django.forms.models import BaseModelFormSet from django.forms.models import BaseModelFormSet
from django.test import SimpleTestCase from django.test import TestCase, skipUnlessDBFeature
from django.test.utils import isolate_apps from django.test.utils import isolate_apps
from .models import Band, Song, User, ValidationTestInlineModel, ValidationTestModel from .models import Band, Song, User, ValidationTestInlineModel, ValidationTestModel
class CheckTestCase(SimpleTestCase): class CheckTestCase(TestCase):
def assertIsInvalid( def assertIsInvalid(
self, self,
model_admin, model_admin,
@ -97,6 +98,29 @@ class RawIdCheckTests(CheckTestCase):
self.assertIsValid(TestModelAdmin, ValidationTestModel) self.assertIsValid(TestModelAdmin, ValidationTestModel)
@isolate_apps("modeladmin")
def assertGeneratedDateTimeFieldIsValid(self, *, db_persist):
class TestModel(Model):
date = models.DateTimeField()
date_copy = models.GeneratedField(
expression=F("date"),
output_field=models.DateTimeField(),
db_persist=db_persist,
)
class TestModelAdmin(ModelAdmin):
date_hierarchy = "date_copy"
self.assertIsValid(TestModelAdmin, TestModel)
@skipUnlessDBFeature("supports_stored_generated_columns")
def test_valid_case_stored_generated_field(self):
self.assertGeneratedDateTimeFieldIsValid(db_persist=True)
@skipUnlessDBFeature("supports_virtual_generated_columns")
def test_valid_case_virtual_generated_field(self):
self.assertGeneratedDateTimeFieldIsValid(db_persist=False)
def test_field_attname(self): def test_field_attname(self):
class TestModelAdmin(ModelAdmin): class TestModelAdmin(ModelAdmin):
raw_id_fields = ["band_id"] raw_id_fields = ["band_id"]
@ -1029,6 +1053,33 @@ class DateHierarchyCheckTests(CheckTestCase):
"admin.E128", "admin.E128",
) )
@isolate_apps("modeladmin")
def assertGeneratedIntegerFieldIsInvalid(self, *, db_persist):
class TestModel(Model):
generated = models.GeneratedField(
expression=models.Value(1),
output_field=models.IntegerField(),
db_persist=db_persist,
)
class TestModelAdmin(ModelAdmin):
date_hierarchy = "generated"
self.assertIsInvalid(
TestModelAdmin,
TestModel,
"The value of 'date_hierarchy' must be a DateField or DateTimeField.",
"admin.E128",
)
@skipUnlessDBFeature("supports_stored_generated_columns")
def test_related_invalid_field_type_stored_generated_field(self):
self.assertGeneratedIntegerFieldIsInvalid(db_persist=True)
@skipUnlessDBFeature("supports_virtual_generated_columns")
def test_related_invalid_field_type_virtual_generated_field(self):
self.assertGeneratedIntegerFieldIsInvalid(db_persist=False)
def test_valid_case(self): def test_valid_case(self):
class TestModelAdmin(ModelAdmin): class TestModelAdmin(ModelAdmin):
date_hierarchy = "pub_date" date_hierarchy = "pub_date"