mirror of https://github.com/django/django.git
Fixed #34842 -- Fixed ModelAdmin.readonly_fields crash with GeneratedFields.
This commit is contained in:
parent
aebedb7bd1
commit
2f1ab16be5
|
@ -199,7 +199,7 @@ class DeferredAttribute:
|
||||||
val = self._check_parent_chain(instance)
|
val = self._check_parent_chain(instance)
|
||||||
if val is None:
|
if val is None:
|
||||||
if instance.pk is None and self.field.generated:
|
if instance.pk is None and self.field.generated:
|
||||||
raise FieldError(
|
raise AttributeError(
|
||||||
"Cannot read a generated field from an unsaved model."
|
"Cannot read a generated field from an unsaved model."
|
||||||
)
|
)
|
||||||
instance.refresh_from_db(fields=[field_name])
|
instance.refresh_from_db(fields=[field_name])
|
||||||
|
|
|
@ -119,6 +119,7 @@ from .models import (
|
||||||
Simple,
|
Simple,
|
||||||
Sketch,
|
Sketch,
|
||||||
Song,
|
Song,
|
||||||
|
Square,
|
||||||
State,
|
State,
|
||||||
Story,
|
Story,
|
||||||
StumpJoke,
|
StumpJoke,
|
||||||
|
@ -1175,6 +1176,10 @@ class TravelerAdmin(admin.ModelAdmin):
|
||||||
autocomplete_fields = ["living_country"]
|
autocomplete_fields = ["living_country"]
|
||||||
|
|
||||||
|
|
||||||
|
class SquareAdmin(admin.ModelAdmin):
|
||||||
|
readonly_fields = ("area",)
|
||||||
|
|
||||||
|
|
||||||
site = admin.AdminSite(name="admin")
|
site = admin.AdminSite(name="admin")
|
||||||
site.site_url = "/my-site-url/"
|
site.site_url = "/my-site-url/"
|
||||||
site.register(Article, ArticleAdmin)
|
site.register(Article, ArticleAdmin)
|
||||||
|
@ -1298,6 +1303,7 @@ site.register(UserProxy)
|
||||||
site.register(Box)
|
site.register(Box)
|
||||||
site.register(Country, CountryAdmin)
|
site.register(Country, CountryAdmin)
|
||||||
site.register(Traveler, TravelerAdmin)
|
site.register(Traveler, TravelerAdmin)
|
||||||
|
site.register(Square, SquareAdmin)
|
||||||
|
|
||||||
# Register core models we need in our tests
|
# Register core models we need in our tests
|
||||||
site.register(User, UserAdmin)
|
site.register(User, UserAdmin)
|
||||||
|
|
|
@ -1134,3 +1134,14 @@ class Traveler(models.Model):
|
||||||
related_name="favorite_country_to_vacation_set",
|
related_name="favorite_country_to_vacation_set",
|
||||||
limit_choices_to={"continent": Country.ASIA},
|
limit_choices_to={"continent": Country.ASIA},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Square(models.Model):
|
||||||
|
side = models.IntegerField()
|
||||||
|
area = models.GeneratedField(
|
||||||
|
db_persist=True,
|
||||||
|
expression=models.F("side") * models.F("side"),
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
required_db_features = {"supports_stored_generated_columns"}
|
||||||
|
|
|
@ -6861,6 +6861,11 @@ class ReadonlyTest(AdminFieldExtractionMixin, TestCase):
|
||||||
field = self.get_admin_readonly_field(response, "plotdetails")
|
field = self.get_admin_readonly_field(response, "plotdetails")
|
||||||
self.assertEqual(field.contents(), "-") # default empty value
|
self.assertEqual(field.contents(), "-") # default empty value
|
||||||
|
|
||||||
|
@skipUnlessDBFeature("supports_stored_generated_columns")
|
||||||
|
def test_readonly_unsaved_generated_field(self):
|
||||||
|
response = self.client.get(reverse("admin:admin_views_square_add"))
|
||||||
|
self.assertContains(response, '<div class="readonly">-</div>')
|
||||||
|
|
||||||
@ignore_warnings(category=RemovedInDjango60Warning)
|
@ignore_warnings(category=RemovedInDjango60Warning)
|
||||||
def test_readonly_field_overrides(self):
|
def test_readonly_field_overrides(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
from django.core.exceptions import FieldError
|
|
||||||
from django.db import IntegrityError, connection
|
from django.db import IntegrityError, connection
|
||||||
from django.db.models import F, FloatField, GeneratedField, IntegerField, Model
|
from django.db.models import F, FloatField, GeneratedField, IntegerField, Model
|
||||||
from django.db.models.functions import Lower
|
from django.db.models.functions import Lower
|
||||||
|
@ -93,7 +92,7 @@ class GeneratedFieldTestMixin:
|
||||||
def test_unsaved_error(self):
|
def test_unsaved_error(self):
|
||||||
m = self.base_model(a=1, b=2)
|
m = self.base_model(a=1, b=2)
|
||||||
msg = "Cannot read a generated field from an unsaved model."
|
msg = "Cannot read a generated field from an unsaved model."
|
||||||
with self.assertRaisesMessage(FieldError, msg):
|
with self.assertRaisesMessage(AttributeError, msg):
|
||||||
m.field
|
m.field
|
||||||
|
|
||||||
def test_create(self):
|
def test_create(self):
|
||||||
|
|
Loading…
Reference in New Issue