mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-13 16:54:47 +03:00
Merge 8de6a6ca60
into c0166d95bb
This commit is contained in:
commit
5ffd1481dc
|
@ -1496,6 +1496,8 @@ class ModelSerializer(Serializer):
|
||||||
default = unique_constraint_field.default
|
default = unique_constraint_field.default
|
||||||
elif unique_constraint_field.null:
|
elif unique_constraint_field.null:
|
||||||
default = None
|
default = None
|
||||||
|
elif unique_constraint_field.blank:
|
||||||
|
default = ''
|
||||||
else:
|
else:
|
||||||
default = empty
|
default = empty
|
||||||
|
|
||||||
|
|
|
@ -149,6 +149,14 @@ class UniquenessTogetherModel(models.Model):
|
||||||
unique_together = ('race_name', 'position')
|
unique_together = ('race_name', 'position')
|
||||||
|
|
||||||
|
|
||||||
|
class BlankUniquenessTogetherModel(models.Model):
|
||||||
|
race_name = models.CharField(max_length=100, blank=True)
|
||||||
|
position = models.IntegerField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
unique_together = ('race_name', 'position')
|
||||||
|
|
||||||
|
|
||||||
class NullUniquenessTogetherModel(models.Model):
|
class NullUniquenessTogetherModel(models.Model):
|
||||||
"""
|
"""
|
||||||
Used to ensure that null values are not included when checking
|
Used to ensure that null values are not included when checking
|
||||||
|
@ -176,6 +184,12 @@ class UniquenessTogetherSerializer(serializers.ModelSerializer):
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
class BlankUniquenessTogetherSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = BlankUniquenessTogetherModel
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
class NullUniquenessTogetherSerializer(serializers.ModelSerializer):
|
class NullUniquenessTogetherSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = NullUniquenessTogetherModel
|
model = NullUniquenessTogetherModel
|
||||||
|
@ -461,6 +475,34 @@ class TestUniquenessTogetherValidation(TestCase):
|
||||||
serializer = NullUniquenessTogetherSerializer(data=data)
|
serializer = NullUniquenessTogetherSerializer(data=data)
|
||||||
assert not serializer.is_valid()
|
assert not serializer.is_valid()
|
||||||
|
|
||||||
|
def test_validation_for_provided_blank_fields(self):
|
||||||
|
BlankUniquenessTogetherModel.objects.create(
|
||||||
|
position=1
|
||||||
|
)
|
||||||
|
data = {
|
||||||
|
'race_name': '',
|
||||||
|
'position': 1
|
||||||
|
}
|
||||||
|
serializer = BlankUniquenessTogetherSerializer(data=data)
|
||||||
|
assert not serializer.is_valid()
|
||||||
|
|
||||||
|
def test_validation_for_missing_blank_fields(self):
|
||||||
|
BlankUniquenessTogetherModel.objects.create(
|
||||||
|
position=1
|
||||||
|
)
|
||||||
|
data = {
|
||||||
|
'position': 1
|
||||||
|
}
|
||||||
|
serializer = BlankUniquenessTogetherSerializer(data=data)
|
||||||
|
assert not serializer.is_valid()
|
||||||
|
|
||||||
|
def test_ignore_validation_for_missing_blank_fields(self):
|
||||||
|
data = {
|
||||||
|
'position': 1
|
||||||
|
}
|
||||||
|
serializer = BlankUniquenessTogetherSerializer(data=data)
|
||||||
|
assert serializer.is_valid(), serializer.errors
|
||||||
|
|
||||||
def test_ignore_validation_for_unchanged_fields(self):
|
def test_ignore_validation_for_unchanged_fields(self):
|
||||||
"""
|
"""
|
||||||
If all fields in the unique together constraint are unchanged,
|
If all fields in the unique together constraint are unchanged,
|
||||||
|
@ -589,6 +631,18 @@ class UniqueConstraintModel(models.Model):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class UniqueConstraintBlankModel(models.Model):
|
||||||
|
title = models.CharField(max_length=100, blank=True)
|
||||||
|
age = models.IntegerField()
|
||||||
|
tag = models.CharField(max_length=100, blank=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
constraints = [
|
||||||
|
# Unique constraint on 2 blank fields
|
||||||
|
models.UniqueConstraint(name='unique_constraint', fields=('age', 'tag'), condition=~models.Q(models.Q(title='') & models.Q(tag='True')))
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class UniqueConstraintNullableModel(models.Model):
|
class UniqueConstraintNullableModel(models.Model):
|
||||||
title = models.CharField(max_length=100)
|
title = models.CharField(max_length=100)
|
||||||
age = models.IntegerField(null=True)
|
age = models.IntegerField(null=True)
|
||||||
|
@ -607,6 +661,12 @@ class UniqueConstraintSerializer(serializers.ModelSerializer):
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
class UniqueConstraintBlankSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = UniqueConstraintBlankModel
|
||||||
|
fields = ('title', 'age', 'tag')
|
||||||
|
|
||||||
|
|
||||||
class UniqueConstraintNullableSerializer(serializers.ModelSerializer):
|
class UniqueConstraintNullableSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = UniqueConstraintNullableModel
|
model = UniqueConstraintNullableModel
|
||||||
|
@ -714,6 +774,12 @@ class TestUniqueConstraintValidation(TestCase):
|
||||||
ids_in_qs = {frozenset(v.queryset.values_list(flat=True)) for v in validators if hasattr(v, "queryset")}
|
ids_in_qs = {frozenset(v.queryset.values_list(flat=True)) for v in validators if hasattr(v, "queryset")}
|
||||||
assert ids_in_qs == {frozenset([1]), frozenset([3])}
|
assert ids_in_qs == {frozenset([1]), frozenset([3])}
|
||||||
|
|
||||||
|
def test_blank_uqnique_constraint_fields_are_not_required(self):
|
||||||
|
serializer = UniqueConstraintBlankSerializer(data={'age': 25})
|
||||||
|
self.assertTrue(serializer.is_valid(), serializer.errors)
|
||||||
|
result = serializer.save()
|
||||||
|
self.assertIsInstance(result, UniqueConstraintBlankModel)
|
||||||
|
|
||||||
def test_nullable_unique_constraint_fields_are_not_required(self):
|
def test_nullable_unique_constraint_fields_are_not_required(self):
|
||||||
serializer = UniqueConstraintNullableSerializer(data={'title': 'Bob'})
|
serializer = UniqueConstraintNullableSerializer(data={'title': 'Bob'})
|
||||||
self.assertTrue(serializer.is_valid(), serializer.errors)
|
self.assertTrue(serializer.is_valid(), serializer.errors)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user