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.
This commit is contained in:
parent
0bf7b25f8f
commit
9142bebff2
|
@ -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()
|
||||
|
|
|
@ -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``
|
||||
--------
|
||||
|
|
|
@ -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``
|
||||
|
|
|
@ -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',
|
||||
),
|
||||
]
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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')
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue