@@ -1427,20 +1427,33 @@ 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),
1430
+ Returns iterator of (fields, queryset, condition_fields, condition, message, code ),
1431
1431
each entry describes an unique together constraint on `fields` in `queryset`
1432
- with respect of constraint's `condition`.
1432
+ with respect of constraint's `condition`, optional custom `violation_error_message` and `violation_error_code` .
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
1436
+ yield unique_together , model ._default_manager , [], None , None , 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
- yield (constraint .fields , model ._default_manager , condition_fields , 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
+ )
1444
1457
1445
1458
def get_uniqueness_extra_kwargs (self , field_names , declared_fields , extra_kwargs ):
1446
1459
"""
@@ -1473,7 +1486,7 @@ def get_uniqueness_extra_kwargs(self, field_names, declared_fields, extra_kwargs
1473
1486
1474
1487
# Include each of the `unique_together` and `UniqueConstraint` field names,
1475
1488
# so long as all the field names are included on the serializer.
1476
- for unique_together_list , queryset , condition_fields , condition in self .get_unique_together_constraints (model ):
1489
+ for unique_together_list , queryset , condition_fields , condition , * __ in self .get_unique_together_constraints (model ):
1477
1490
unique_together_list_and_condition_fields = set (unique_together_list ) | set (condition_fields )
1478
1491
if model_fields_names .issuperset (unique_together_list_and_condition_fields ):
1479
1492
unique_constraint_names |= unique_together_list_and_condition_fields
@@ -1598,7 +1611,7 @@ def get_unique_together_validators(self):
1598
1611
# Note that we make sure to check `unique_together` both on the
1599
1612
# base model class, but also on any parent classes.
1600
1613
validators = []
1601
- for unique_together , queryset , condition_fields , condition in self .get_unique_together_constraints (self .Meta .model ):
1614
+ for unique_together , queryset , condition_fields , condition , message , code in self .get_unique_together_constraints (self .Meta .model ):
1602
1615
# Skip if serializer does not map to all unique together sources
1603
1616
unique_together_and_condition_fields = set (unique_together ) | set (condition_fields )
1604
1617
if not set (source_map ).issuperset (unique_together_and_condition_fields ):
@@ -1626,6 +1639,8 @@ def get_unique_together_validators(self):
1626
1639
fields = field_names ,
1627
1640
condition_fields = tuple (source_map [f ][0 ] for f in condition_fields ),
1628
1641
condition = condition ,
1642
+ message = message ,
1643
+ code = code ,
1629
1644
)
1630
1645
validators .append (validator )
1631
1646
return validators
0 commit comments