DecimalValidator

Валидатор DecimalValidator применяется к полям форм Django для проверки десятичных чисел. Он ограничивает общее количество цифр и количество знаков после запятой. Валидатор принимает два параметра: max_digits - максимальное общее количество цифр (включая знаки после запятой), и decimal_places - максимальное количество знаков после запятой. Валидатор генерирует ошибку проверки, если число превышает установленные ограничения.

Синтаксис

pythonfrom django.core.validators import DecimalValidator

validator = DecimalValidator(max_digits, decimal_places)

Пример

Создадим форму с полем для ввода цены товара, ограничив общее количество цифр до 5, а знаков после запятой до 2:

pythonfrom django import forms
from django.core.validators import DecimalValidator

class ProductForm(forms.Form):
  price = forms.DecimalField(
    validators=[DecimalValidator(max_digits=5, decimal_places=2)]
  )

Попробуем передать в форму разные значения и выведем результат проверки:

pythonfrom django.core.exceptions import ValidationError

validator = DecimalValidator(max_digits=5, decimal_places=2)

test_values = ["123.45", "1234.56", "12345.67", "123.456"]

for value in test_values:
  try:
    validator(value)
    print(f'"{value} is valid"')
  except ValidationError as e:
    print(f'"{value} is invalid: {e.message}"')

Результат выполнения кода:

python"123.45 is valid"
"1234.56 is invalid: Ensure that there are no more than 5 digits in total."
"12345.67 is invalid: Ensure that there are no more than 5 digits in total."
"123.456 is invalid: Ensure that there are no more than 2 decimal places."

Пример

Используем валидатор в модели Django. Создадим модель Product с полем price, ограничив общее количество цифр до 6, а знаков после запятой до 3:

pythonfrom django.db import models
from django.core.validators import DecimalValidator

class Product(models.Model):
  name = models.CharField(max_length=100)
  price = models.DecimalField(
    max_digits=6,
    decimal_places=3,
    validators=[DecimalValidator(max_digits=6, decimal_places=3)]
  )
  
  def __str__(self):
    return self.name

Теперь создадим экземпляр модели и попробуем сохранить его с разными значениями:

pythonfrom myapp.models import Product
from django.core.exceptions import ValidationError

try:
  product = Product(name="Smartphone", price=999.999)
  product.full_clean()
  print("Product is valid")
except ValidationError as e:
  print(f"Validation error: {e.message_dict}")
  
try:
  product = Product(name="Laptop", price=1000.99)
  product.full_clean()
  print("Product is valid")
except ValidationError as e:
  print(f"Validation error: {e.message_dict}")

Результат выполнения кода:

python"Product is valid"
"Validation error: {'price': ['Ensure that there are no more than 6 digits in total.']}"

Пример

Используем валидатор в форме с обработкой ошибок в шаблоне. Создадим форму для расчета стоимости заказа:

pythonfrom django import forms
from django.core.validators import DecimalValidator

class OrderForm(forms.Form):
  total_price = forms.DecimalField(
    validators=[DecimalValidator(max_digits=10, decimal_places=2)],
    help_text="Максимум 10 цифр, 2 знака после запятой"
  )
  discount = forms.DecimalField(
    validators=[DecimalValidator(max_digits=5, decimal_places=2)],
    help_text="Максимум 5 цифр, 2 знака после запятой"
  )
  
  def clean(self):
    cleaned_data = super().clean()
    total_price = cleaned_data.get("total_price")
    discount = cleaned_data.get("discount")
    
    if total_price and discount and discount > total_price:
      raise forms.ValidationError("Скидка не может быть больше общей суммы")
    
    return cleaned_data

Проверим работу формы с корректными и некорректными данными:

pythonform_data = {
  "total_price": "1500.50",
  "discount": "150.25"
}

form = OrderForm(form_data)
if form.is_valid():
  print("Form is valid")
  print(f"Total: {form.cleaned_data['total_price']}, Discount: {form.cleaned_data['discount']}")
else:
  print(f"Form errors: {form.errors}")
  
form_data_invalid = {
  "total_price": "12345678901.50",
  "discount": "150.25"
}

form = OrderForm(form_data_invalid)
if form.is_valid():
  print("Form is valid")
else:
  print(f"Form errors: {form.errors}")

Результат выполнения кода:

python"Form is valid"
"Total: 1500.50, Discount: 150.25"
"Form errors: {'total_price': ['Ensure that there are no more than 10 digits in total.']}"

Смотрите также

  • валидатор MaxValueValidator,
    который проверяет, что значение не превышает заданный максимум
  • валидатор MinValueValidator,
    который проверяет, что значение не меньше заданного минимума
  • поле DecimalField,
    которое используется для работы с десятичными числами в формах
  • валидатор StepValueValidator,
    который проверяет, что значение кратно заданному шагу