Проверка модели в django-rest-framework
У меня есть модель Django с пользовательским кодом проверки. Когда я использую django-rest-framework, чтобы попытаться создать / обновить модель, проверочный код запускается, но вместо вывода некоторого содержимого JSON с ошибкой он завершается ошибкой с ValidationError. Почему django-rest-framework не улавливает эту ошибку?
models.py
class MyModel(models.Model):
is_default = models.BooleanField()
type = models.CharField(max_length=64, choices=[("a","a"), ("b","b"), ("c","c")]
def clean(self, *args, **kwargs):
# there can be only 1 "default" model per type
if self.is_default:
other_models = MyModel.objects.filter(
type=self.type,
default=True).exclude(pk=self.pk)
if other_models.count() != 0:
raise ValidationError({"default": "There can be only one default model per type.")
super(MyModel, self).clean(*args, **kwargs)
serializers.py
class MyModelSerializer(ModelSerializer):
class Meta:
model = MyModel
fields = ('id', 'default', 'type')
Когда я пытаюсь отправить данные JSON, где type="d", я правильно получаю следующий ответ: { "type": ["this is not one of the valid choices"]}
,
Но когда я пытаюсь POST JSON-данные, где default=true (и в БД уже есть модели по умолчанию того же типа), я просто поднимаю ValidationError вместо красиво отформатированного JSON.
1 ответ
Первая ошибка валидации работает, потому что DRF ее вызывает.
Только подклассы DRFs APIException
подняты в рамках. Так что вам нужно использовать это APIException
класс, чтобы поднять ошибку.
Например,
from rest_framework.exceptions import APIException
class CustomException(APIException):
status_code = 400
default_detail = 'There can be only one default model per type.'
Тогда вы могли бы сделать это в вашей модели.
if other_models.count() != 0:
raise CustomException()
На заметку, почему вы пытаетесь создать unique together
ограничение на модель с использованием кода? Вы должны сделать это как уровень базы данных, используя unique_together.
Например, на модели вы могли бы сделать что-то вроде этого...
class Meta:
unique_together = ("is_default", "type")
После того, как вы запустите миграцию, он будет считать их уникальными, когда вместе!