Валидация с использованием метода 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.
Класс ValidationError
Django не возвращает ответы в формате JSON. Вы либо:
- Перенесите логику валидации в сериализатор, и пусть логика валидации выбрасывает класс DRF
ValidationError
. См. docs. .
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
- Создайте пользовательский обработчик ошибок для перехвата
ValidationError
от Django и возврата HTTP-ответа. См. docs. .
# 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",
}