Проверка модели в 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")

После того, как вы запустите миграцию, он будет считать их уникальными, когда вместе!

Другие вопросы по тегам