Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit e454758

Browse filesBrowse files
authored
Fix regression in unique_together validation with SerializerMethodField (#9712)
1 parent 33d59fe commit e454758
Copy full SHA for e454758

File tree

Expand file treeCollapse file tree

2 files changed

+39
-1
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+39
-1
lines changed

‎rest_framework/serializers.py

Copy file name to clipboardExpand all lines: rest_framework/serializers.py
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1469,12 +1469,13 @@ def get_uniqueness_extra_kwargs(self, field_names, declared_fields, extra_kwargs
14691469
model_field.unique_for_year}
14701470

14711471
unique_constraint_names -= {None}
1472+
model_fields_names = set(model_fields.keys())
14721473

14731474
# Include each of the `unique_together` and `UniqueConstraint` field names,
14741475
# so long as all the field names are included on the serializer.
14751476
for unique_together_list, queryset, condition_fields, condition in self.get_unique_together_constraints(model):
14761477
unique_together_list_and_condition_fields = set(unique_together_list) | set(condition_fields)
1477-
if set(field_names).issuperset(unique_together_list_and_condition_fields):
1478+
if model_fields_names.issuperset(unique_together_list_and_condition_fields):
14781479
unique_constraint_names |= unique_together_list_and_condition_fields
14791480

14801481
# Now we have all the field names that have uniqueness constraints

‎tests/test_validators.py

Copy file name to clipboardExpand all lines: tests/test_validators.py
+37Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,43 @@ def filter(self, **kwargs):
516516
validator.filter_queryset(attrs=data, queryset=queryset, serializer=serializer)
517517
assert queryset.called_with == {'race_name': 'bar', 'position': 1}
518518

519+
def test_uniq_together_validation_uses_model_fields_method_field(self):
520+
class TestSerializer(serializers.ModelSerializer):
521+
position = serializers.SerializerMethodField()
522+
523+
def get_position(self, obj):
524+
return obj.position or 0
525+
526+
class Meta:
527+
model = NullUniquenessTogetherModel
528+
fields = ['race_name', 'position']
529+
530+
serializer = TestSerializer()
531+
expected = dedent("""
532+
TestSerializer():
533+
race_name = CharField(max_length=100)
534+
position = SerializerMethodField()
535+
""")
536+
assert repr(serializer) == expected
537+
538+
def test_uniq_together_validation_uses_model_fields_with_source_field(self):
539+
class TestSerializer(serializers.ModelSerializer):
540+
pos = serializers.IntegerField(source='position')
541+
542+
class Meta:
543+
model = NullUniquenessTogetherModel
544+
fields = ['race_name', 'pos']
545+
546+
serializer = TestSerializer()
547+
expected = dedent("""
548+
TestSerializer():
549+
race_name = CharField(max_length=100, required=True)
550+
pos = IntegerField(source='position')
551+
class Meta:
552+
validators = [<UniqueTogetherValidator(queryset=NullUniquenessTogetherModel.objects.all(), fields=('race_name', 'pos'))>]
553+
""")
554+
assert repr(serializer) == expected
555+
519556

520557
class UniqueConstraintModel(models.Model):
521558
race_name = models.CharField(max_length=100)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.