1
0
mirror of https://github.com/django/django.git synced 2025-06-02 10:09:12 +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: if not self.foreign_related_fields:
return [] return []
unique_foreign_fields = { has_unique_constraint = any(
frozenset([f.name]) rel_field.unique for rel_field in self.foreign_related_fields
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}
) )
unique_foreign_fields.update( if not has_unique_constraint:
{ foreign_fields = {f.name for f in self.foreign_related_fields}
frozenset(uc.fields) remote_opts = self.remote_field.model._meta
for uc in self.remote_field.model._meta.total_unique_constraints has_unique_constraint = any(
} frozenset(ut) <= foreign_fields for ut in remote_opts.unique_together
) ) or any(
foreign_fields = {f.name for f in self.foreign_related_fields} frozenset(uc.fields) <= foreign_fields
has_unique_constraint = any(u <= foreign_fields for u in unique_foreign_fields) for uc in remote_opts.total_unique_constraints
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
) )
model_name = self.remote_field.model.__name__
return [ if not has_unique_constraint:
checks.Error( if len(self.foreign_related_fields) > 1:
"No subset of the fields %s on model '%s' is unique." field_combination = ", ".join(
% (field_combination, model_name), f"'{rel_field.name}'" for rel_field in self.foreign_related_fields
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",
) )
] model_name = self.remote_field.model.__name__
elif not has_unique_constraint: return [
field_name = self.foreign_related_fields[0].name checks.Error(
model_name = self.remote_field.model.__name__ f"No subset of the fields {field_combination} on model "
return [ f"'{model_name}' is unique.",
checks.Error( hint=(
"'%s.%s' must be unique because it is referenced by " "Mark a single field as unique=True or add a set of "
"a foreign key." % (model_name, field_name), "fields to a unique constraint (via unique_together "
hint=( "or a UniqueConstraint (without condition) in the "
"Add unique=True to this field or add a " "model Meta.constraints)."
"UniqueConstraint (without condition) in the model " ),
"Meta.constraints." obj=self,
), id="fields.E310",
obj=self, )
id="fields.E311", ]
) else:
] field_name = self.foreign_related_fields[0].name
else: model_name = self.remote_field.model.__name__
return [] 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): def deconstruct(self):
name, path, args, kwargs = super().deconstruct() name, path, args, kwargs = super().deconstruct()