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:
parent
894fa55da1
commit
e5ec11a84d
@ -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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user