Использование метода очистки моделей для проверки полей - PullRequest
0 голосов
/ 19 февраля 2020

Мне нужно проверить в поле модели список доступных элементов, прежде чем я сохраню их в базе данных.

models.py

class Vendors(models.Model):
    COUNTRY_CHOICES = tuple(countries)
    ...
    country = models.CharField(max_length=45, choices=COUNTRY_CHOICES)
    ...

класс для сохранения моделей

class CsvToDatabase(APIView):

    def post(self, request, format=None):
        data = request.data
        for key, vendor in data.items():
            Vendors(
                ...,
                country=vendor['Country'],
                ...,

            ).save()

        return Response({'received data': request.data,
                         'message': 'Vendors from vendors_list were successfully added to the database'})

Для проверки я добавил clean метод к моделям

def clean(self):
    if self.country not in [x[1] for x in countries]:
        raise ValidationError(detail="Country name does not match to the country list ")

Но это не работает

Следующий шаг Я добавил тот же код к методу save

def save(self):
    if self.country not in [x[1] for x in countries]:
        raise ValidationError(detail="Country name does not match to the country list ")

И это работает, но я прочитал, что с использованием проверки в метод сохранения неверен. И правильный способ использования - clean , почему в моем случае это не работает?

1 Ответ

1 голос
/ 19 февраля 2020

См. проверка модели для полного объяснения того, как работает проверка моделей.

Вкратце: для проверки объекта вам необходимо вызвать full_clean() для объекта. Это не происходит автоматически! Это происходит, когда:

  • Вы используете ModelForm и вызываете is_valid() в форме
  • Вы используете ModelSerializer в DRF и вызываете is_valid() на сериализаторе
  • Вы вызываете full_clean() явно

В вашем случае просто создайте объект, вызовите full_clean(), а затем save(). Обратите внимание, что вам даже не нужно добавлять свою собственную проверку (метод clean()), потому что проверка на действительный выбор автоматически выполняется Django во время clean_fields(), когда choices установлено в поле:

v = Vendors(country=vendor['country'], ...)
try:
    v.full_clean()
except ValidationError as e:
    # do something e.g. return error response
v.save()
return Response(...)
...