Валидация с использованием метода clean в models.Model Django

Если категория "автомобиль", то я бы хотел, чтобы поле x было пустым.

Я пытаюсь использовать чистый метод для проверки полей, поэтому если категория равна "автомобили", то поле x не должно быть введено. Я пробовал что-то вроде этого, но это не работает правильно.

class Category(models.Model):
    name = models.CharField(primary_key=True, max_length=100)

    def __str__(self):
        return self.name

class Product(models.Model):
    def save(self, **kwargs):
        self.clean()
        return super(Product, self).save(**kwargs)

    def clean(self):
        if self.category == "cars" and self.x is not None:
            raise ValidationError(
                _('information'))

    category = models.ForeignKey(
        Category, on_delete=models.PROTECT, default='cars')
    x = models.CharField(
        max_length=10, choices=X_OPTIONS, blank=True)

When I am sending category: "cars", x: "sth", it doesn't send a clearly json information back to client. It just shows the information on django console with traceback.

Класс ValidationErrorDjango не возвращает ответы в формате JSON. Вы либо:

  1. Перенесите логику валидации в сериализатор, и пусть логика валидации выбрасывает класс DRF ValidationError. См. docs.
  2. .
class ProductSerializer(serializers.ModelSerializer):
    # ...

    class Meta:
        model = Product
        # ...

    def validate(self, data):
        if not data["x"] and data["category"] == "cars":
            raise serializers.ValidationError(
                _("information")
            )
        return data
  1. Создайте пользовательский обработчик ошибок для перехвата ValidationError от Django и возврата HTTP-ответа. См. docs.
  2. .
# myapp/api/exceptions.py

from django.core.exceptions import ValidationError

from rest_framework.views import exception_handler
from rest_framework.response import Response

def django_error_handler(exc, context):
    """Handle django core's errors."""
    response = exception_handler(exc, context)
    if response is None and isinstance(exc, ValidationError):
        return Response(status=400, data=exc.message_dict)
    return response


# settings.py

REST_FRAMEWORK = {
    # ...
    "EXCEPTION_HANDLER": "myapp.api.exceptions.django_error_handler",
}
Вернуться на верх