@@ -1427,33 +1427,20 @@ def get_extra_kwargs(self):
1427
1427
1428
1428
def get_unique_together_constraints (self , model ):
1429
1429
"""
1430
- Returns iterator of (fields, queryset, condition_fields, condition, message, code ),
1430
+ Returns iterator of (fields, queryset, condition_fields, condition),
1431
1431
each entry describes an unique together constraint on `fields` in `queryset`
1432
- with respect of constraint's `condition`, optional custom `violation_error_message` and `violation_error_code` .
1432
+ with respect of constraint's `condition`.
1433
1433
"""
1434
1434
for parent_class in [model ] + list (model ._meta .parents ):
1435
1435
for unique_together in parent_class ._meta .unique_together :
1436
- yield unique_together , model ._default_manager , [], None , None , None
1436
+ yield unique_together , model ._default_manager , [], None
1437
1437
for constraint in parent_class ._meta .constraints :
1438
1438
if isinstance (constraint , models .UniqueConstraint ) and len (constraint .fields ) > 1 :
1439
1439
if constraint .condition is None :
1440
1440
condition_fields = []
1441
1441
else :
1442
1442
condition_fields = list (get_referenced_base_fields_from_q (constraint .condition ))
1443
-
1444
- violation_error_message = constraint .get_violation_error_message ()
1445
- default_error_message = constraint .default_violation_error_message % {"name" : constraint .name }
1446
- if violation_error_message == default_error_message :
1447
- violation_error_message = None
1448
-
1449
- yield (
1450
- constraint .fields ,
1451
- model ._default_manager ,
1452
- condition_fields ,
1453
- constraint .condition ,
1454
- violation_error_message ,
1455
- getattr (constraint , "violation_error_code" , None )
1456
- )
1443
+ yield (constraint .fields , model ._default_manager , condition_fields , constraint .condition )
1457
1444
1458
1445
def get_uniqueness_extra_kwargs (self , field_names , declared_fields , extra_kwargs ):
1459
1446
"""
@@ -1486,7 +1473,7 @@ def get_uniqueness_extra_kwargs(self, field_names, declared_fields, extra_kwargs
1486
1473
1487
1474
# Include each of the `unique_together` and `UniqueConstraint` field names,
1488
1475
# so long as all the field names are included on the serializer.
1489
- for unique_together_list , queryset , condition_fields , condition , * __ in self .get_unique_together_constraints (model ):
1476
+ for unique_together_list , queryset , condition_fields , condition in self .get_unique_together_constraints (model ):
1490
1477
unique_together_list_and_condition_fields = set (unique_together_list ) | set (condition_fields )
1491
1478
if model_fields_names .issuperset (unique_together_list_and_condition_fields ):
1492
1479
unique_constraint_names |= unique_together_list_and_condition_fields
@@ -1582,6 +1569,17 @@ def get_validators(self):
1582
1569
self .get_unique_for_date_validators ()
1583
1570
)
1584
1571
1572
+ def _get_constraint_violation_error_message (self , constraint ):
1573
+ """
1574
+ Returns the violation error message for the UniqueConstraint,
1575
+ or None if the message is the default.
1576
+ """
1577
+ violation_error_message = constraint .get_violation_error_message ()
1578
+ default_error_message = constraint .default_violation_error_message % {"name" : constraint .name }
1579
+ if violation_error_message == default_error_message :
1580
+ return None
1581
+ return violation_error_message
1582
+
1585
1583
def get_unique_together_validators (self ):
1586
1584
"""
1587
1585
Determine a default set of validators for any unique_together constraints.
@@ -1608,10 +1606,15 @@ def get_unique_together_validators(self):
1608
1606
for name , source in field_sources .items ():
1609
1607
source_map [source ].append (name )
1610
1608
1609
+ unique_constraint_by_fields = {
1610
+ constraint .fields : constraint for constraint in self .Meta .model ._meta .constraints
1611
+ if isinstance (constraint , models .UniqueConstraint )
1612
+ }
1613
+
1611
1614
# Note that we make sure to check `unique_together` both on the
1612
1615
# base model class, but also on any parent classes.
1613
1616
validators = []
1614
- for unique_together , queryset , condition_fields , condition , message , code in self .get_unique_together_constraints (self .Meta .model ):
1617
+ for unique_together , queryset , condition_fields , condition in self .get_unique_together_constraints (self .Meta .model ):
1615
1618
# Skip if serializer does not map to all unique together sources
1616
1619
unique_together_and_condition_fields = set (unique_together ) | set (condition_fields )
1617
1620
if not set (source_map ).issuperset (unique_together_and_condition_fields ):
@@ -1634,13 +1637,17 @@ def get_unique_together_validators(self):
1634
1637
)
1635
1638
1636
1639
field_names = tuple (source_map [f ][0 ] for f in unique_together )
1640
+
1641
+ constraint = unique_constraint_by_fields .get (tuple (unique_together ), None )
1642
+ violation_error_message = self ._get_constraint_violation_error_message (constraint ) if constraint else None
1643
+
1637
1644
validator = UniqueTogetherValidator (
1638
1645
queryset = queryset ,
1639
1646
fields = field_names ,
1640
1647
condition_fields = tuple (source_map [f ][0 ] for f in condition_fields ),
1641
1648
condition = condition ,
1642
- message = message ,
1643
- code = code ,
1649
+ message = violation_error_message ,
1650
+ code = getattr ( constraint , 'violation_error_code' , None ) ,
1644
1651
)
1645
1652
validators .append (validator )
1646
1653
return validators
0 commit comments