Django has it’s built-in validators which you can use, however if you want to write your own custom validation:

from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import gettext_lazy as _

def validate_positive(value):
    if value < 0:
        raise ValidationError(
            _("%(value)s is not positive."),
            params={"value": value}

class Book(models.Model):
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    title = models.CharField(max_length=120)
    price = models.DecimalField(validators=[validate_positive])

With validate_positive validator we ensure that price is always positive.


validators param always must be a list, even though there is one validator.

By the way you don’t need to use gettext_lazy but it’s a good habit for i18n.

All done!