Browse Source

Refs #11964 -- Changed CheckConstraint() signature to use keyword-only arguments.

Also renamed the `constraint` argument to `check` to better represent which
part of the constraint the provided `Q` object represents.
Simon Charette 6 years ago
parent
commit
9142bebff2

+ 6 - 6
django/db/models/constraints.py

@@ -4,13 +4,13 @@ __all__ = ['CheckConstraint']
 
 
 class CheckConstraint:
-    def __init__(self, constraint, name):
-        self.constraint = constraint
+    def __init__(self, *, check, name):
+        self.check = check
         self.name = name
 
     def constraint_sql(self, model, schema_editor):
         query = Query(model)
-        where = query.build_where(self.constraint)
+        where = query.build_where(self.check)
         connection = schema_editor.connection
         compiler = connection.ops.compiler('SQLCompiler')(query, connection, 'default')
         sql, params = where.as_sql(compiler, connection)
@@ -35,19 +35,19 @@ class CheckConstraint:
         }
 
     def __repr__(self):
-        return "<%s: constraint='%s' name='%s'>" % (self.__class__.__name__, self.constraint, self.name)
+        return "<%s: check='%s' name=%r>" % (self.__class__.__name__, self.check, self.name)
 
     def __eq__(self, other):
         return (
             isinstance(other, CheckConstraint) and
             self.name == other.name and
-            self.constraint == other.constraint
+            self.check == other.check
         )
 
     def deconstruct(self):
         path = '%s.%s' % (self.__class__.__module__, self.__class__.__name__)
         path = path.replace('django.db.models.constraints', 'django.db.models')
-        return (path, (), {'constraint': self.constraint, 'name': self.name})
+        return (path, (), {'check': self.check, 'name': self.name})
 
     def clone(self):
         _, args, kwargs = self.deconstruct()

+ 7 - 7
docs/ref/models/check-constraints.txt

@@ -23,20 +23,20 @@ explains the API references of :class:`CheckConstraint`.
 ``CheckConstraint`` options
 ===========================
 
-.. class:: CheckConstraint(constraint, name)
+.. class:: CheckConstraint(*, check, name)
 
     Creates a check constraint in the database.
 
-``constraint``
---------------
+``check``
+---------
 
-.. attribute:: CheckConstraint.constraint
+.. attribute:: CheckConstraint.check
 
-A :class:`Q` object that specifies the condition you want the constraint to
+A :class:`Q` object that specifies the check you want the constraint to
 enforce.
 
-For example ``CheckConstraint(Q(age__gte=18), 'age_gte_18')`` ensures the age
-field is never less than 18.
+For example ``CheckConstraint(check=Q(age__gte=18), name='age_gte_18')``
+ensures the age field is never less than 18.
 
 ``name``
 --------

+ 1 - 1
docs/ref/models/options.txt

@@ -469,7 +469,7 @@ Django quotes column and table names behind the scenes.
 
             class Meta:
                 constraints = [
-                    models.CheckConstraint(models.Q(age__gte=18), 'age_gte_18'),
+                    models.CheckConstraint(check=models.Q(age__gte=18), name='age_gte_18'),
                 ]
 
 ``verbose_name``

+ 3 - 3
tests/constraints/models.py

@@ -9,7 +9,7 @@ class Product(models.Model):
     class Meta:
         constraints = [
             models.CheckConstraint(
-                models.Q(price__gt=models.F('discounted_price')),
-                'price_gt_discounted_price'
-            )
+                check=models.Q(price__gt=models.F('discounted_price')),
+                name='price_gt_discounted_price',
+            ),
         ]

+ 8 - 8
tests/constraints/tests.py

@@ -6,22 +6,22 @@ from .models import Product
 
 class CheckConstraintTests(TestCase):
     def test_repr(self):
-        constraint = models.Q(price__gt=models.F('discounted_price'))
+        check = models.Q(price__gt=models.F('discounted_price'))
         name = 'price_gt_discounted_price'
-        check = models.CheckConstraint(constraint, name)
+        constraint = models.CheckConstraint(check=check, name=name)
         self.assertEqual(
-            repr(check),
-            "<CheckConstraint: constraint='{}' name='{}'>".format(constraint, name),
+            repr(constraint),
+            "<CheckConstraint: check='{}' name='{}'>".format(check, name),
         )
 
     def test_deconstruction(self):
-        constraint = models.Q(price__gt=models.F('discounted_price'))
+        check = models.Q(price__gt=models.F('discounted_price'))
         name = 'price_gt_discounted_price'
-        check = models.CheckConstraint(constraint, name)
-        path, args, kwargs = check.deconstruct()
+        constraint = models.CheckConstraint(check=check, name=name)
+        path, args, kwargs = constraint.deconstruct()
         self.assertEqual(path, 'django.db.models.CheckConstraint')
         self.assertEqual(args, ())
-        self.assertEqual(kwargs, {'constraint': constraint, 'name': name})
+        self.assertEqual(kwargs, {'check': check, 'name': name})
 
     @skipUnlessDBFeature('supports_table_check_constraints')
     def test_database_constraint(self):

+ 1 - 1
tests/invalid_models_tests/test_models.py

@@ -1003,7 +1003,7 @@ class ConstraintsTests(SimpleTestCase):
             age = models.IntegerField()
 
             class Meta:
-                constraints = [models.CheckConstraint(models.Q(age__gte=18), 'is_adult')]
+                constraints = [models.CheckConstraint(check=models.Q(age__gte=18), name='is_adult')]
 
         errors = Model.check()
         warn = Warning(

+ 4 - 4
tests/migrations/test_autodetector.py

@@ -65,7 +65,7 @@ class AutodetectorTests(TestCase):
         ("id", models.AutoField(primary_key=True)),
         ("name", models.CharField(max_length=200)),
     ],
-        {'constraints': [models.CheckConstraint(models.Q(name__contains='Bob'), 'name_contains_bob')]},
+        {'constraints': [models.CheckConstraint(check=models.Q(name__contains='Bob'), name='name_contains_bob')]},
     )
     author_dates_of_birth_auto_now = ModelState("testapp", "Author", [
         ("id", models.AutoField(primary_key=True)),
@@ -1399,9 +1399,9 @@ class AutodetectorTests(TestCase):
         author = ModelState('otherapp', 'Author', [
             ('id', models.AutoField(primary_key=True)),
             ('name', models.CharField(max_length=200)),
-        ], {'constraints': [models.CheckConstraint(models.Q(name__contains='Bob'), 'name_contains_bob')]})
+        ], {'constraints': [models.CheckConstraint(check=models.Q(name__contains='Bob'), name='name_contains_bob')]})
         changes = self.get_changes([], [author])
-        added_constraint = models.CheckConstraint(models.Q(name__contains='Bob'), 'name_contains_bob')
+        added_constraint = models.CheckConstraint(check=models.Q(name__contains='Bob'), name='name_contains_bob')
         # Right number of migrations?
         self.assertEqual(len(changes['otherapp']), 1)
         # Right number of actions?
@@ -1417,7 +1417,7 @@ class AutodetectorTests(TestCase):
         changes = self.get_changes([self.author_name], [self.author_name_check_constraint])
         self.assertNumberMigrations(changes, 'testapp', 1)
         self.assertOperationTypes(changes, 'testapp', 0, ['AddConstraint'])
-        added_constraint = models.CheckConstraint(models.Q(name__contains='Bob'), 'name_contains_bob')
+        added_constraint = models.CheckConstraint(check=models.Q(name__contains='Bob'), name='name_contains_bob')
         self.assertOperationAttributes(changes, 'testapp', 0, 0, model_name='author', constraint=added_constraint)
 
     def test_remove_constraints(self):

+ 3 - 3
tests/migrations/test_operations.py

@@ -110,7 +110,7 @@ class OperationTestBase(MigrationTestBase):
         if check_constraint:
             operations.append(migrations.AddConstraint(
                 "Pony",
-                models.CheckConstraint(models.Q(pink__gt=2), name="pony_test_constraint")
+                models.CheckConstraint(check=models.Q(pink__gt=2), name="pony_test_constraint")
             ))
         if second_model:
             operations.append(migrations.CreateModel(
@@ -471,7 +471,7 @@ class OperationTests(OperationTestBase):
     @skipUnlessDBFeature('supports_table_check_constraints')
     def test_create_model_with_constraint(self):
         where = models.Q(pink__gt=2)
-        check_constraint = models.CheckConstraint(where, name='test_constraint_pony_pink_gt_2')
+        check_constraint = models.CheckConstraint(check=where, name='test_constraint_pony_pink_gt_2')
         operation = migrations.CreateModel(
             "Pony",
             [
@@ -1782,7 +1782,7 @@ class OperationTests(OperationTestBase):
         project_state = self.set_up_test_model('test_addconstraint')
 
         where = models.Q(pink__gt=2)
-        check_constraint = models.CheckConstraint(where, name='test_constraint_pony_pink_gt_2')
+        check_constraint = models.CheckConstraint(check=where, name='test_constraint_pony_pink_gt_2')
         operation = migrations.AddConstraint('Pony', check_constraint)
         self.assertEqual(operation.describe(), 'Create constraint test_constraint_pony_pink_gt_2 on model Pony')
 

+ 1 - 1
tests/migrations/test_state.py

@@ -1143,7 +1143,7 @@ class ModelStateTests(SimpleTestCase):
             size = models.IntegerField()
 
             class Meta:
-                constraints = [models.CheckConstraint(models.Q(size__gt=1), 'size_gt_1')]
+                constraints = [models.CheckConstraint(check=models.Q(size__gt=1), name='size_gt_1')]
 
         state = ModelState.from_model(ModelWithConstraints)
         model_constraints = ModelWithConstraints._meta.constraints