summaryrefslogtreecommitdiff
path: root/tests/invalid_models_tests
diff options
context:
space:
mode:
authorValze <xypzin2010@gmail.com>2020-02-19 23:57:16 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-02-27 10:53:29 +0100
commit5bf28ac2ed17773214bd6c7796ef356067c9fa91 (patch)
tree0a06a71188c3e1380c5ec561078de6cd4f53caa1 /tests/invalid_models_tests
parent41ebe60728a15aa273f4d70de92f5246a89c3d4e (diff)
downloaddjango-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.py144
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',