mirror of
https://github.com/django/django.git
synced 2025-10-09 23:09: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:
parent
308f674e6d
commit
8c621e9642
@ -1357,7 +1357,7 @@ class Model(AltersData, metaclass=ModelBase):
|
|||||||
meta = meta or self._meta
|
meta = meta or self._meta
|
||||||
field_map = {}
|
field_map = {}
|
||||||
generated_fields = []
|
generated_fields = []
|
||||||
for field in meta.local_concrete_fields:
|
for field in meta.local_fields:
|
||||||
if field.name in exclude:
|
if field.name in exclude:
|
||||||
continue
|
continue
|
||||||
if field.generated:
|
if field.generated:
|
||||||
@ -1368,7 +1368,19 @@ class Model(AltersData, metaclass=ModelBase):
|
|||||||
continue
|
continue
|
||||||
generated_fields.append(field)
|
generated_fields.append(field)
|
||||||
continue
|
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"):
|
if not value or not hasattr(value, "resolve_expression"):
|
||||||
value = Value(value, field)
|
value = Value(value, field)
|
||||||
field_map[field.name] = value
|
field_map[field.name] = value
|
||||||
|
@ -3,10 +3,10 @@ import datetime
|
|||||||
import pickle
|
import pickle
|
||||||
from operator import attrgetter
|
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.db import connection, models
|
||||||
from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature
|
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 django.utils import translation
|
||||||
|
|
||||||
from .models import (
|
from .models import (
|
||||||
@ -771,7 +771,30 @@ class TestCachedPathInfo(TestCase):
|
|||||||
|
|
||||||
|
|
||||||
class ForeignObjectModelValidationTests(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")
|
@skipUnlessDBFeature("supports_table_check_constraints")
|
||||||
def test_validate_constraints_excluding_foreign_object(self):
|
def test_validate_constraints_excluding_foreign_object(self):
|
||||||
customer_tab = CustomerTab(customer_id=150)
|
customer_tab = CustomerTab(customer_id=150)
|
||||||
customer_tab.validate_constraints(exclude={"customer"})
|
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"})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user