summaryrefslogtreecommitdiff
path: root/tests/constraints
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2019-11-15 00:08:36 -0500
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2019-11-21 11:56:35 +0100
commite9a0e1d4f6ecfc4227acff74e1f56f288a0b30aa (patch)
treedeecc4f80b577d47f03e8ade90f410aa4cf32e07 /tests/constraints
parent37e6c5b79bd0529a3c85b8c478e4002fd33a2a1d (diff)
downloaddjango-e9a0e1d4f6ecfc4227acff74e1f56f288a0b30aa.tar.gz
Fixed #30484 -- Added conditional expressions support to CheckConstraint.
Diffstat (limited to 'tests/constraints')
-rw-r--r--tests/constraints/models.py13
-rw-r--r--tests/constraints/tests.py21
2 files changed, 34 insertions, 0 deletions
diff --git a/tests/constraints/models.py b/tests/constraints/models.py
index d207de6e73..cadeea887e 100644
--- a/tests/constraints/models.py
+++ b/tests/constraints/models.py
@@ -18,6 +18,19 @@ class Product(models.Model):
check=models.Q(price__gt=0),
name='%(app_label)s_%(class)s_price_gt_0',
),
+ models.CheckConstraint(
+ check=models.expressions.RawSQL(
+ 'price < %s', (1000,), output_field=models.BooleanField()
+ ),
+ name='%(app_label)s_price_lt_1000_raw',
+ ),
+ models.CheckConstraint(
+ check=models.expressions.ExpressionWrapper(
+ models.Q(price__gt=500) | models.Q(price__lt=500),
+ output_field=models.BooleanField()
+ ),
+ name='%(app_label)s_price_neq_500_wrap',
+ ),
]
diff --git a/tests/constraints/tests.py b/tests/constraints/tests.py
index 8e2eb11e2a..136060eb07 100644
--- a/tests/constraints/tests.py
+++ b/tests/constraints/tests.py
@@ -61,6 +61,13 @@ class CheckConstraintTests(TestCase):
"<CheckConstraint: check='{}' name='{}'>".format(check, name),
)
+ def test_invalid_check_types(self):
+ msg = (
+ 'CheckConstraint.check must be a Q instance or boolean expression.'
+ )
+ with self.assertRaisesMessage(TypeError, msg):
+ models.CheckConstraint(check=models.F('discounted_price'), name='check')
+
def test_deconstruction(self):
check = models.Q(price__gt=models.F('discounted_price'))
name = 'price_gt_discounted_price'
@@ -76,11 +83,25 @@ class CheckConstraintTests(TestCase):
with self.assertRaises(IntegrityError):
Product.objects.create(price=10, discounted_price=20)
+ @skipUnlessDBFeature('supports_table_check_constraints')
+ def test_database_constraint_expression(self):
+ Product.objects.create(price=999, discounted_price=5)
+ with self.assertRaises(IntegrityError):
+ Product.objects.create(price=1000, discounted_price=5)
+
+ @skipUnlessDBFeature('supports_table_check_constraints')
+ def test_database_constraint_expressionwrapper(self):
+ Product.objects.create(price=499, discounted_price=5)
+ with self.assertRaises(IntegrityError):
+ Product.objects.create(price=500, discounted_price=5)
+
@skipUnlessDBFeature('supports_table_check_constraints', 'can_introspect_check_constraints')
def test_name(self):
constraints = get_constraints(Product._meta.db_table)
for expected_name in (
'price_gt_discounted_price',
+ 'constraints_price_lt_1000_raw',
+ 'constraints_price_neq_500_wrap',
'constraints_product_price_gt_0',
):
with self.subTest(expected_name):