Hi folks,
We've had check constraints for a while now and they're awesome.
I'd like to propose an alternative way to declare check constraints: at the
field level. This sounds like it's duplicating the feature but there are
some advantages that make this distinct from declaring at the model-level
from the meta:
- Colocality: the check rules are close to the field they're concerned
with
- Reusability: Allows for bundling with custom field types
- Good for checks concerned only with the field its declared on, for
multiple fields recommended to continue to use Meta. (Kind of analogous to
unique=True vs UniqueConstraint)
For example:
class Product(Model):
price = DecimalField(..., check=Q(price__gte=0))
...
other fields
...
class Meta:
constraints = [
... declare constraints here that are concerned with multiple
fields...
]
For more complex fields you can then bundle the check for reusability:
class PriceField(DecimalField):
def contribute_to_class(self, ...):
super().contribute_to_class(...)
self.check = Q(**{f'{self.name}__gte': 0})
Some other points:
- To be consistent with model-level check constraints they'd also need
to participate in validate_constraints().
- (Small)PositiveIntegerField already has its own implementation of a
check constraint, enforcing values >- 0 via the private db_check() method.
I think this is an example of how bundling checks can be useful.
- I won't go into implementation alternatives but making use of this
existing db_check() method is one possibility. How participation in
validation would work would still need to be decided upon.
- See this Stupid Django Trick
<https://github.com/shangxiao/stupid-django-tricks/tree/master/column_check_constraints>
for some experimentation with this idea.
Cheers,
David
--
You received this message because you are subscribed to the Google Groups
"Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-developers/CADyZw-6Odv0dpo-En3Jm2NqPhBtK7ebaGKBi4OROe1n%2BvHEE-A%40mail.gmail.com.