114
You can use Django’s built-in validators –
from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator
class MyModel(models.Model):
qty = models.IntegerField(
default=1,
validators=[MaxValueValidator(100), MinValueValidator(1)]
)
NOTE:
- The validators will not run automatically when you save a model, but if you are using a ModelForm, it will run your validators on the fields that are included in the form. Check this link for more info.
- To enforce constraints on a database level refer to maertejin’s answer below.
7
Since Django 2.2 you can enforce the constraints on a database level with CheckConstraint:
class MyModel(models.Model):
qty = models.IntegerField()
class Meta:
constraints = [
models.CheckConstraint(
check=models.Q(qty__gte=1) & models.Q(qty__lt=10),
name="A qty value is valid between 1 and 10",
)
]
- [Django]-CSV new-line character seen in unquoted field error
- [Django]-How can I programmatically obtain the max_length of a Django model field?
- [Django]-Django 1.11 TypeError context must be a dict rather than Context
6
You will have to create a custom validator
from django.core.exceptions import ValidationError
def validate_number(value):
if something : # Your conditions here
raise ValidationError('%s some error message' % value)
And then use this validator in your model
from django.db import models
class MyModel(models.Model):
field = models.IntegerField(validators=[validate_number])
- [Django]-Create empty queryset by default in django form fields
- [Django]-Aggregating save()s in Django?
- [Django]-*_set attributes on Django Models
1
For better code reusability you can create custom RangeIntegerField
from django.core.validators import MinValueValidator, MaxValueValidator
from django.db import models
class RangeIntegerField(models.IntegerField):
def __init__(self, *args, **kwargs):
validators = kwargs.pop("validators", [])
# turn min_value and max_value params into validators
min_value = kwargs.pop("min_value", None)
if min_value is not None:
validators.append(MinValueValidator(min_value))
max_value = kwargs.pop("max_value", None)
if max_value is not None:
validators.append(MaxValueValidator(max_value))
kwargs["validators"] = validators
super().__init__(*args, **kwargs)
You can use this Field
in your models
class SomeModel(models.Model):
some_value = RangeIntegerField(min_value=42, max_value=451)
It plays well with both django-forms and DRF’s serializers
- [Django]-Django Rest Framework remove csrf
- [Django]-User Authentication in Django Rest Framework + Angular.js web app
- [Django]-How to See if a String Contains Another String in Django Template
-2
If you are using postgres, you can use range fields to specify the range.
Check this: Range Fields in django
- [Django]-Django's self.client.login(…) does not work in unit tests
- [Django]-Passing variable urlname to url tag in django template
- [Django]-Django AutoField with primary_key vs default pk
Source:stackexchange.com