@@ -1430,15 +1430,18 @@ def get_unique_together_constraints(self, model):
1430
1430
"""
1431
1431
for parent_class in [model ] + list (model ._meta .parents ):
1432
1432
for unique_together in parent_class ._meta .unique_together :
1433
- yield unique_together , model ._default_manager
1433
+ yield unique_together , model ._default_manager , []
1434
1434
for constraint in parent_class ._meta .constraints :
1435
1435
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 )
1442
1445
1443
1446
def get_uniqueness_extra_kwargs (self , field_names , declared_fields , extra_kwargs ):
1444
1447
"""
@@ -1470,9 +1473,9 @@ def get_uniqueness_extra_kwargs(self, field_names, declared_fields, extra_kwargs
1470
1473
1471
1474
# Include each of the `unique_together` and `UniqueConstraint` field names,
1472
1475
# 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 ) )
1476
1479
1477
1480
# Now we have all the field names that have uniqueness constraints
1478
1481
# applied, we can add the extra 'required=...' or 'default=...'
@@ -1592,12 +1595,12 @@ def get_unique_together_validators(self):
1592
1595
# Note that we make sure to check `unique_together` both on the
1593
1596
# base model class, but also on any parent classes.
1594
1597
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 ):
1596
1599
# 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 ) ):
1598
1601
continue
1599
1602
1600
- for source in unique_together :
1603
+ for source in ( * unique_together , * condition_fields ) :
1601
1604
assert len (source_map [source ]) == 1 , (
1602
1605
"Unable to create `UniqueTogetherValidator` for "
1603
1606
"`{model}.{field}` as `{serializer}` has multiple "
@@ -1614,9 +1617,9 @@ def get_unique_together_validators(self):
1614
1617
)
1615
1618
1616
1619
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 )
1617
1621
validator = UniqueTogetherValidator (
1618
- queryset = queryset ,
1619
- fields = field_names
1622
+ queryset = queryset , fields = field_names , condition_fields = condition_fields
1620
1623
)
1621
1624
validators .append (validator )
1622
1625
return validators
0 commit comments