mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-10-31 07:57:55 +03:00 
			
		
		
		
	Fix raising on nullable fields part of UniqueConstraint (#9531)
				
					
				
			* Add test to reproduce problem with nullable fields part of a unique constraint Ref #9378 * Simplify test case and add similar case for unique_together * Add test for unique together in a better place * Default nullable fields to null in unique constraints checks * Remove redundant test and move other to more appropriate place
This commit is contained in:
		
							parent
							
								
									dbac145638
								
							
						
					
					
						commit
						a8595a8eae
					
				|  | @ -1490,6 +1490,8 @@ class ModelSerializer(Serializer): | |||
|                 default = timezone.now | ||||
|             elif unique_constraint_field.has_default(): | ||||
|                 default = unique_constraint_field.default | ||||
|             elif unique_constraint_field.null: | ||||
|                 default = None | ||||
|             else: | ||||
|                 default = empty | ||||
| 
 | ||||
|  |  | |||
|  | @ -441,6 +441,14 @@ class TestUniquenessTogetherValidation(TestCase): | |||
|         serializer = NullUniquenessTogetherSerializer(data=data) | ||||
|         assert serializer.is_valid() | ||||
| 
 | ||||
|     def test_ignore_validation_for_missing_nullable_fields(self): | ||||
|         data = { | ||||
|             'date': datetime.date(2000, 1, 1), | ||||
|             'race_name': 'Paris Marathon', | ||||
|         } | ||||
|         serializer = NullUniquenessTogetherSerializer(data=data) | ||||
|         assert serializer.is_valid(), serializer.errors | ||||
| 
 | ||||
|     def test_do_not_ignore_validation_for_null_fields(self): | ||||
|         # None values that are not on fields part of the uniqueness constraint | ||||
|         # do not cause the instance to skip validation. | ||||
|  | @ -539,12 +547,30 @@ class UniqueConstraintModel(models.Model): | |||
|         ] | ||||
| 
 | ||||
| 
 | ||||
| class UniqueConstraintNullableModel(models.Model): | ||||
|     title = models.CharField(max_length=100) | ||||
|     age = models.IntegerField(null=True) | ||||
|     tag = models.CharField(max_length=100, null=True) | ||||
| 
 | ||||
|     class Meta: | ||||
|         constraints = [ | ||||
|             # Unique constraint on 2 nullable fields | ||||
|             models.UniqueConstraint(name='unique_constraint', fields=('age', 'tag')) | ||||
|         ] | ||||
| 
 | ||||
| 
 | ||||
| class UniqueConstraintSerializer(serializers.ModelSerializer): | ||||
|     class Meta: | ||||
|         model = UniqueConstraintModel | ||||
|         fields = '__all__' | ||||
| 
 | ||||
| 
 | ||||
| class UniqueConstraintNullableSerializer(serializers.ModelSerializer): | ||||
|     class Meta: | ||||
|         model = UniqueConstraintNullableModel | ||||
|         fields = ('title', 'age', 'tag') | ||||
| 
 | ||||
| 
 | ||||
| class TestUniqueConstraintValidation(TestCase): | ||||
|     def setUp(self): | ||||
|         self.instance = UniqueConstraintModel.objects.create( | ||||
|  | @ -611,6 +637,12 @@ class TestUniqueConstraintValidation(TestCase): | |||
|         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])} | ||||
| 
 | ||||
|     def test_nullable_unique_constraint_fields_are_not_required(self): | ||||
|         serializer = UniqueConstraintNullableSerializer(data={'title': 'Bob'}) | ||||
|         self.assertTrue(serializer.is_valid(), serializer.errors) | ||||
|         result = serializer.save() | ||||
|         self.assertIsInstance(result, UniqueConstraintNullableModel) | ||||
| 
 | ||||
| 
 | ||||
| # Tests for `UniqueForDateValidator` | ||||
| # ---------------------------------- | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user