1
0
mirror of https://github.com/django/django.git synced 2025-10-09 06:49:12 +00:00

Fixed #36580 -- Fixed constraint validation crash when condition uses a ForeignObject.

Follow-up to e44e8327d3d88d86895735c0e427102063ff5b55. Refs #36222.
This commit is contained in:
SaJH 2025-09-15 19:55:55 -04:00 committed by Jacob Walls
parent 308f674e6d
commit 8c621e9642
2 changed files with 39 additions and 4 deletions

View File

@ -1357,7 +1357,7 @@ class Model(AltersData, metaclass=ModelBase):
meta = meta or self._meta
field_map = {}
generated_fields = []
for field in meta.local_concrete_fields:
for field in meta.local_fields:
if field.name in exclude:
continue
if field.generated:
@ -1368,7 +1368,19 @@ class Model(AltersData, metaclass=ModelBase):
continue
generated_fields.append(field)
continue
value = getattr(self, field.attname)
if (
isinstance(field.remote_field, ForeignObjectRel)
and field not in meta.local_concrete_fields
):
value = tuple(
getattr(self, from_field) for from_field in field.from_fields
)
if len(value) == 1:
value = value[0]
elif field.concrete:
value = getattr(self, field.attname)
else:
continue
if not value or not hasattr(value, "resolve_expression"):
value = Value(value, field)
field_map[field.name] = value

View File

@ -3,10 +3,10 @@ import datetime
import pickle
from operator import attrgetter
from django.core.exceptions import FieldError
from django.core.exceptions import FieldError, ValidationError
from django.db import connection, models
from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature
from django.test.utils import isolate_apps
from django.test.utils import CaptureQueriesContext, isolate_apps
from django.utils import translation
from .models import (
@ -771,7 +771,30 @@ class TestCachedPathInfo(TestCase):
class ForeignObjectModelValidationTests(TestCase):
@skipUnlessDBFeature("supports_table_check_constraints")
def test_validate_constraints_with_foreign_object(self):
customer_tab = CustomerTab(customer_id=1500)
with self.assertRaisesMessage(ValidationError, "customer_id_limit"):
customer_tab.validate_constraints()
@skipUnlessDBFeature("supports_table_check_constraints")
def test_validate_constraints_success_case_single_query(self):
customer_tab = CustomerTab(customer_id=500)
with CaptureQueriesContext(connection) as ctx:
customer_tab.validate_constraints()
select_queries = [
query["sql"]
for query in ctx.captured_queries
if "select" in query["sql"].lower()
]
self.assertEqual(len(select_queries), 1)
@skipUnlessDBFeature("supports_table_check_constraints")
def test_validate_constraints_excluding_foreign_object(self):
customer_tab = CustomerTab(customer_id=150)
customer_tab.validate_constraints(exclude={"customer"})
@skipUnlessDBFeature("supports_table_check_constraints")
def test_validate_constraints_excluding_foreign_object_member(self):
customer_tab = CustomerTab(customer_id=150)
customer_tab.validate_constraints(exclude={"customer_id"})