1
0
mirror of https://github.com/django/django.git synced 2025-03-13 10:50:55 +00:00

Fixed #35285 -- Optimized ForeignObject._check_unique_target().

This commit is contained in:
Adam Johnson 2024-03-08 22:01:11 +00:00 committed by Mariusz Felisiak
parent 894fa55da1
commit e5ec11a84d

View File

@ -615,60 +615,56 @@ class ForeignObject(RelatedField):
if not self.foreign_related_fields:
return []
unique_foreign_fields = {
frozenset([f.name])
for f in self.remote_field.model._meta.get_fields()
if getattr(f, "unique", False)
}
unique_foreign_fields.update(
{frozenset(ut) for ut in self.remote_field.model._meta.unique_together}
has_unique_constraint = any(
rel_field.unique for rel_field in self.foreign_related_fields
)
unique_foreign_fields.update(
{
frozenset(uc.fields)
for uc in self.remote_field.model._meta.total_unique_constraints
}
)
foreign_fields = {f.name for f in self.foreign_related_fields}
has_unique_constraint = any(u <= foreign_fields for u in unique_foreign_fields)
if not has_unique_constraint and len(self.foreign_related_fields) > 1:
field_combination = ", ".join(
"'%s'" % rel_field.name for rel_field in self.foreign_related_fields
if not has_unique_constraint:
foreign_fields = {f.name for f in self.foreign_related_fields}
remote_opts = self.remote_field.model._meta
has_unique_constraint = any(
frozenset(ut) <= foreign_fields for ut in remote_opts.unique_together
) or any(
frozenset(uc.fields) <= foreign_fields
for uc in remote_opts.total_unique_constraints
)
model_name = self.remote_field.model.__name__
return [
checks.Error(
"No subset of the fields %s on model '%s' is unique."
% (field_combination, model_name),
hint=(
"Mark a single field as unique=True or add a set of "
"fields to a unique constraint (via unique_together "
"or a UniqueConstraint (without condition) in the "
"model Meta.constraints)."
),
obj=self,
id="fields.E310",
if not has_unique_constraint:
if len(self.foreign_related_fields) > 1:
field_combination = ", ".join(
f"'{rel_field.name}'" for rel_field in self.foreign_related_fields
)
]
elif not has_unique_constraint:
field_name = self.foreign_related_fields[0].name
model_name = self.remote_field.model.__name__
return [
checks.Error(
"'%s.%s' must be unique because it is referenced by "
"a foreign key." % (model_name, field_name),
hint=(
"Add unique=True to this field or add a "
"UniqueConstraint (without condition) in the model "
"Meta.constraints."
),
obj=self,
id="fields.E311",
)
]
else:
return []
model_name = self.remote_field.model.__name__
return [
checks.Error(
f"No subset of the fields {field_combination} on model "
f"'{model_name}' is unique.",
hint=(
"Mark a single field as unique=True or add a set of "
"fields to a unique constraint (via unique_together "
"or a UniqueConstraint (without condition) in the "
"model Meta.constraints)."
),
obj=self,
id="fields.E310",
)
]
else:
field_name = self.foreign_related_fields[0].name
model_name = self.remote_field.model.__name__
return [
checks.Error(
f"'{model_name}.{field_name}' must be unique because it is "
"referenced by a foreign key.",
hint=(
"Add unique=True to this field or add a "
"UniqueConstraint (without condition) in the model "
"Meta.constraints."
),
obj=self,
id="fields.E311",
)
]
return []
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()