@@ -1430,15 +1430,18 @@ def get_unique_together_constraints(self, model):
14301430 """
14311431 for parent_class in [model ] + list (model ._meta .parents ):
14321432 for unique_together in parent_class ._meta .unique_together :
1433- yield unique_together , model ._default_manager
1433+ yield unique_together , model ._default_manager , []
14341434 for constraint in parent_class ._meta .constraints :
14351435 if isinstance (constraint , models .UniqueConstraint ) and len (constraint .fields ) > 1 :
1436- yield (
1437- constraint .fields ,
1438- model ._default_manager
1439- if constraint .condition is None
1440- else model ._default_manager .filter (constraint .condition )
1441- )
1436+ if constraint .condition is None :
1437+ queryset = model ._default_manager
1438+ condition_fields = []
1439+ else :
1440+ queryset = model ._default_manager .filter (constraint .condition )
1441+ condition_fields = [
1442+ f [0 ].split ("__" )[0 ] for f in constraint .condition .children
1443+ ]
1444+ yield (constraint .fields , queryset , condition_fields )
14421445
14431446 def get_uniqueness_extra_kwargs (self , field_names , declared_fields , extra_kwargs ):
14441447 """
@@ -1470,9 +1473,9 @@ def get_uniqueness_extra_kwargs(self, field_names, declared_fields, extra_kwargs
14701473
14711474 # Include each of the `unique_together` and `UniqueConstraint` field names,
14721475 # so long as all the field names are included on the serializer.
1473- for unique_together_list , queryset in self .get_unique_together_constraints (model ):
1474- if set (field_names ).issuperset (unique_together_list ):
1475- unique_constraint_names |= set (unique_together_list )
1476+ for unique_together_list , queryset , condition_fields in self .get_unique_together_constraints (model ):
1477+ if set (field_names ).issuperset (( * unique_together_list , * condition_fields ) ):
1478+ unique_constraint_names |= set (( * unique_together_list , * condition_fields ) )
14761479
14771480 # Now we have all the field names that have uniqueness constraints
14781481 # applied, we can add the extra 'required=...' or 'default=...'
@@ -1592,12 +1595,12 @@ def get_unique_together_validators(self):
15921595 # Note that we make sure to check `unique_together` both on the
15931596 # base model class, but also on any parent classes.
15941597 validators = []
1595- for unique_together , queryset in self .get_unique_together_constraints (self .Meta .model ):
1598+ for unique_together , queryset , condition_fields in self .get_unique_together_constraints (self .Meta .model ):
15961599 # Skip if serializer does not map to all unique together sources
1597- if not set (source_map ).issuperset (unique_together ):
1600+ if not set (source_map ).issuperset (( * unique_together , * condition_fields ) ):
15981601 continue
15991602
1600- for source in unique_together :
1603+ for source in ( * unique_together , * condition_fields ) :
16011604 assert len (source_map [source ]) == 1 , (
16021605 "Unable to create `UniqueTogetherValidator` for "
16031606 "`{model}.{field}` as `{serializer}` has multiple "
@@ -1614,9 +1617,9 @@ def get_unique_together_validators(self):
16141617 )
16151618
16161619 field_names = tuple (source_map [f ][0 ] for f in unique_together )
1620+ condition_fields = tuple (source_map [f ][0 ] for f in condition_fields )
16171621 validator = UniqueTogetherValidator (
1618- queryset = queryset ,
1619- fields = field_names
1622+ queryset = queryset , fields = field_names , condition_fields = condition_fields
16201623 )
16211624 validators .append (validator )
16221625 return validators
0 commit comments