1
0
mirror of https://github.com/django/django.git synced 2024-12-22 09:05:43 +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:
if not isinstance(field, (models.DateField, models.DateTimeField)):
if field.get_internal_type() not in {"DateField", "DateTimeField"}:
return must_be(
"a DateField or DateTimeField",
option="date_hierarchy",

View File

@ -24,3 +24,7 @@ Bugfixes
* Fixed a regression in Django 5.0.7 that caused a crash in
``LocaleMiddleware`` when processing a language code over 500 characters
(: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.sites import AdminSite
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.functions import Upper
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 .models import Band, Song, User, ValidationTestInlineModel, ValidationTestModel
class CheckTestCase(SimpleTestCase):
class CheckTestCase(TestCase):
def assertIsInvalid(
self,
model_admin,
@ -97,6 +98,29 @@ class RawIdCheckTests(CheckTestCase):
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):
class TestModelAdmin(ModelAdmin):
raw_id_fields = ["band_id"]
@ -1029,6 +1053,33 @@ class DateHierarchyCheckTests(CheckTestCase):
"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):
class TestModelAdmin(ModelAdmin):
date_hierarchy = "pub_date"