Skip to content

Commit 10a45ab

Browse files
committed
fix check constraint parsing, closes #36
1 parent fff6d6a commit 10a45ab

File tree

3 files changed

+26
-10
lines changed

3 files changed

+26
-10
lines changed

.gitignore

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,5 @@ __pycache__
88
/build
99
/dist
1010
/.mypy_cache
11-
12-
# Devenv
13-
.devenv*
14-
devenv.local.nix
11+
/.env*
12+
/pyrightconfig.json

src/extra_checks/checks/model_field_checks.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -295,12 +295,16 @@ def apply(
295295
field_choices.append("")
296296
in_name = f"{field.name}__in"
297297
for constraint in model._meta.constraints:
298-
if isinstance(constraint, models.CheckConstraint):
299-
conditions = dict(constraint.check.children) # type: ignore
300-
if in_name in conditions and set(field_choices) == set(
301-
conditions[in_name]
302-
):
303-
return
298+
if isinstance(constraint, models.CheckConstraint) and isinstance(
299+
constraint.check, models.Q
300+
):
301+
for entry in constraint.check.children:
302+
if (
303+
isinstance(entry, tuple)
304+
and entry[0] == in_name
305+
and set(field_choices) == set(entry[1])
306+
):
307+
return
304308
check = f'models.Q({in_name}=[{", ".join([self._repr_choice(c) for c in field_choices])}])'
305309
yield self.message(
306310
"Field with choices must have companion CheckConstraint to enforce choices on database level.",

tests/example/models.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ class ChoicesConstraint(models.Model):
174174
integer_blank_invalid = models.IntegerField(
175175
choices=[(1, "One"), (2, "Two")], blank=True, null=True
176176
)
177+
url = models.URLField(blank=True, null=True)
177178

178179
class Meta:
179180
constraints = [
@@ -199,6 +200,19 @@ class Meta:
199200
name="integer_blank_invalid",
200201
check=models.Q(integer_blank_invalid__in=(1, 2, "")),
201202
),
203+
models.CheckConstraint(
204+
name="unrelated_constraint",
205+
check=(
206+
models.Q(url=None)
207+
| (
208+
(
209+
models.Q(url__startswith="http://")
210+
| models.Q(url__startswith="https://")
211+
)
212+
& models.Q(url__length__lte=2000)
213+
)
214+
),
215+
),
202216
]
203217

204218

0 commit comments

Comments
 (0)