Refs #31187 -- Added total_unique_constraints property to model's Options.

This commit is contained in:
Mariusz Felisiak 2020-02-19 08:14:35 +01:00
parent 73a34f3fa8
commit d270c10a72
2 changed files with 20 additions and 9 deletions

View File

@ -19,7 +19,7 @@ from django.db.models import (
NOT_PROVIDED, ExpressionWrapper, IntegerField, Max, Value,
)
from django.db.models.constants import LOOKUP_SEP
from django.db.models.constraints import CheckConstraint, UniqueConstraint
from django.db.models.constraints import CheckConstraint
from django.db.models.deletion import CASCADE, Collector
from django.db.models.fields.related import (
ForeignObjectRel, OneToOneField, lazy_related_operation, resolve_relation,
@ -1023,12 +1023,14 @@ class Model(metaclass=ModelBase):
unique_checks = []
unique_togethers = [(self.__class__, self._meta.unique_together)]
constraints = [(self.__class__, self._meta.constraints)]
constraints = [(self.__class__, self._meta.total_unique_constraints)]
for parent_class in self._meta.get_parent_list():
if parent_class._meta.unique_together:
unique_togethers.append((parent_class, parent_class._meta.unique_together))
if parent_class._meta.constraints:
constraints.append((parent_class, parent_class._meta.constraints))
if parent_class._meta.total_unique_constraints:
constraints.append(
(parent_class, parent_class._meta.total_unique_constraints)
)
for model_class, unique_together in unique_togethers:
for check in unique_together:
@ -1038,10 +1040,7 @@ class Model(metaclass=ModelBase):
for model_class, model_constraints in constraints:
for constraint in model_constraints:
if (isinstance(constraint, UniqueConstraint) and
# Partial unique constraints can't be validated.
constraint.condition is None and
not any(name in exclude for name in constraint.fields)):
if not any(name in exclude for name in constraint.fields):
unique_checks.append((model_class, constraint.fields))
# These are checks for the unique_for_<date/year/month>.

View File

@ -7,7 +7,7 @@ from django.apps import apps
from django.conf import settings
from django.core.exceptions import FieldDoesNotExist
from django.db import connections
from django.db.models import AutoField, Manager, OrderWrt
from django.db.models import AutoField, Manager, OrderWrt, UniqueConstraint
from django.db.models.query_utils import PathInfo
from django.utils.datastructures import ImmutableList, OrderedSet
from django.utils.functional import cached_property
@ -827,6 +827,18 @@ class Options:
self._get_fields_cache[cache_key] = fields
return fields
@cached_property
def total_unique_constraints(self):
"""
Return a list of total unique constraints. Useful for determining set
of fields guaranteed to be unique for all rows.
"""
return [
constraint
for constraint in self.constraints
if isinstance(constraint, UniqueConstraint) and constraint.condition is None
]
@cached_property
def _property_names(self):
"""Return a set of the names of the properties defined on the model."""