diff options
author | Valze <xypzin2010@gmail.com> | 2020-02-19 23:57:16 +0200 |
---|---|---|
committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2020-02-27 10:53:29 +0100 |
commit | 5bf28ac2ed17773214bd6c7796ef356067c9fa91 (patch) | |
tree | 0a06a71188c3e1380c5ec561078de6cd4f53caa1 /tests/invalid_models_tests | |
parent | 41ebe60728a15aa273f4d70de92f5246a89c3d4e (diff) | |
download | django-5bf28ac2ed17773214bd6c7796ef356067c9fa91.tar.gz |
Fixed #31185 -- Fixed detecting of unique fields in ForeignKey/ForeignObject checks when using Meta.constraints.
Diffstat (limited to 'tests/invalid_models_tests')
-rw-r--r-- | tests/invalid_models_tests/test_relative_fields.py | 144 |
1 files changed, 136 insertions, 8 deletions
diff --git a/tests/invalid_models_tests/test_relative_fields.py b/tests/invalid_models_tests/test_relative_fields.py index 4211973cf3..24f27168c2 100644 --- a/tests/invalid_models_tests/test_relative_fields.py +++ b/tests/invalid_models_tests/test_relative_fields.py @@ -352,7 +352,11 @@ class RelativeFieldTests(SimpleTestCase): field = Model._meta.get_field('foreign_key') self.assertEqual(field.check(), [ Error( - "'Target.bad' must set unique=True because it is referenced by a foreign key.", + "'Target.bad' must be unique because it is referenced by a foreign key.", + hint=( + 'Add unique=True to this field or add a UniqueConstraint ' + '(without condition) in the model Meta.constraints.' + ), obj=field, id='fields.E311', ), @@ -368,12 +372,64 @@ class RelativeFieldTests(SimpleTestCase): field = Model._meta.get_field('field') self.assertEqual(field.check(), [ Error( - "'Target.bad' must set unique=True because it is referenced by a foreign key.", + "'Target.bad' must be unique because it is referenced by a foreign key.", + hint=( + 'Add unique=True to this field or add a UniqueConstraint ' + '(without condition) in the model Meta.constraints.' + ), obj=field, id='fields.E311', ), ]) + def test_foreign_key_to_partially_unique_field(self): + class Target(models.Model): + source = models.IntegerField() + + class Meta: + constraints = [ + models.UniqueConstraint( + fields=['source'], + name='tfktpuf_partial_unique', + condition=models.Q(pk__gt=2), + ), + ] + + class Model(models.Model): + field = models.ForeignKey(Target, models.CASCADE, to_field='source') + + field = Model._meta.get_field('field') + self.assertEqual(field.check(), [ + Error( + "'Target.source' must be unique because it is referenced by a " + "foreign key.", + hint=( + 'Add unique=True to this field or add a UniqueConstraint ' + '(without condition) in the model Meta.constraints.' + ), + obj=field, + id='fields.E311', + ), + ]) + + def test_foreign_key_to_unique_field_with_meta_constraint(self): + class Target(models.Model): + source = models.IntegerField() + + class Meta: + constraints = [ + models.UniqueConstraint( + fields=['source'], + name='tfktufwmc_unique', + ), + ] + + class Model(models.Model): + field = models.ForeignKey(Target, models.CASCADE, to_field='source') + + field = Model._meta.get_field('field') + self.assertEqual(field.check(), []) + def test_foreign_object_to_non_unique_fields(self): class Person(models.Model): # Note that both fields are not unique. @@ -396,14 +452,82 @@ class RelativeFieldTests(SimpleTestCase): Error( "No subset of the fields 'country_id', 'city_id' on model 'Person' is unique.", hint=( - "Add unique=True on any of those fields or add at least " - "a subset of them to a unique_together constraint." + 'Mark a single field as unique=True or add a set of ' + 'fields to a unique constraint (via unique_together or a ' + 'UniqueConstraint (without condition) in the model ' + 'Meta.constraints).' ), obj=field, id='fields.E310', ) ]) + def test_foreign_object_to_partially_unique_field(self): + class Person(models.Model): + country_id = models.IntegerField() + city_id = models.IntegerField() + + class Meta: + constraints = [ + models.UniqueConstraint( + fields=['country_id', 'city_id'], + name='tfotpuf_partial_unique', + condition=models.Q(pk__gt=2), + ), + ] + + class MMembership(models.Model): + person_country_id = models.IntegerField() + person_city_id = models.IntegerField() + person = models.ForeignObject( + Person, + on_delete=models.CASCADE, + from_fields=['person_country_id', 'person_city_id'], + to_fields=['country_id', 'city_id'], + ) + + field = MMembership._meta.get_field('person') + self.assertEqual(field.check(), [ + Error( + "No subset of the fields 'country_id', 'city_id' on model " + "'Person' is unique.", + hint=( + 'Mark a single field as unique=True or add a set of ' + 'fields to a unique constraint (via unique_together or a ' + 'UniqueConstraint (without condition) in the model ' + 'Meta.constraints).' + ), + obj=field, + id='fields.E310', + ), + ]) + + def test_foreign_object_to_unique_field_with_meta_constraint(self): + class Person(models.Model): + country_id = models.IntegerField() + city_id = models.IntegerField() + + class Meta: + constraints = [ + models.UniqueConstraint( + fields=['country_id', 'city_id'], + name='tfotpuf_unique', + ), + ] + + class MMembership(models.Model): + person_country_id = models.IntegerField() + person_city_id = models.IntegerField() + person = models.ForeignObject( + Person, + on_delete=models.CASCADE, + from_fields=['person_country_id', 'person_city_id'], + to_fields=['country_id', 'city_id'], + ) + + field = MMembership._meta.get_field('person') + self.assertEqual(field.check(), []) + def test_on_delete_set_null_on_non_nullable_field(self): class Person(models.Model): pass @@ -1453,8 +1577,10 @@ class M2mThroughFieldsTests(SimpleTestCase): Error( "No subset of the fields 'a', 'b' on model 'Parent' is unique.", hint=( - "Add unique=True on any of those fields or add at least " - "a subset of them to a unique_together constraint." + 'Mark a single field as unique=True or add a set of ' + 'fields to a unique constraint (via unique_together or a ' + 'UniqueConstraint (without condition) in the model ' + 'Meta.constraints).' ), obj=field, id='fields.E310', @@ -1489,8 +1615,10 @@ class M2mThroughFieldsTests(SimpleTestCase): Error( "No subset of the fields 'a', 'b', 'd' on model 'Parent' is unique.", hint=( - "Add unique=True on any of those fields or add at least " - "a subset of them to a unique_together constraint." + 'Mark a single field as unique=True or add a set of ' + 'fields to a unique constraint (via unique_together or a ' + 'UniqueConstraint (without condition) in the model ' + 'Meta.constraints).' ), obj=field, id='fields.E310', |