LINUX.ORG.RU

Django валидация объекта

 


0

1

Добрый вечер. Банальная ситуация. 2 модели:

  • 1. товар (имя, наличие на складе и т.п)
  • 2. продажа

При «продаже» «товар» должен быть в наличии иначе выкидывается ошибка. Вопрос где эту валидацию проводить? Как я понял с использованием Django-Rest-Framework всю логику работы с данными (валидация, корректировка данных) проводится в Serializer классе модели? Но если мы захотим не использовать Rest-Framework, а пользоваться обычной формой, то нам уже в классе формы надо прописывать валидацию? Но это уже дублирование кода.

В модели, как описано тут: https://docs.djangoproject.com/en/2.1/ref/validators/#writing-validators

Тут мы получаем только значение поля, но нет информации, о самом объекте.

Прошу совета, кто и как справляется с подобными вещами?



Последнее исправление: hell_wood (всего исправлений: 1)

Это уже бизнес-логика, а не валидация. Валидация это проверка на то, что тебе корректные данные прислали, например - email это корректный email, число не слишком большое, пароль не слишком короткий и т.п.

pawnhearts ★★★★★
()
Ответ на: комментарий от pawnhearts

Окей. бизнес логика где тогда лучше ее размещать? Чтобы и не привязана была к модели отображения, сериализации, формы и т.п. И ошибку выдавала, если в модели в методе save выдавать исключение ValidationError, то сервер падает с 500-ой ошибкой, а по идее должна быть 400-ая ошибка и указание на не корректное поле.

hell_wood
() автор топика
Ответ на: комментарий от pawnhearts

view для одного урла будет. А если нам нужно эту логику применять в другой вьюхе? Тащить код, тоже не хорошо. Логичнее, вроде как, в модели, но как быть с выводом сообщения об ошибке?

hell_wood
() автор топика
Ответ на: комментарий от hell_wood

Тут мы получаем только значение поля, но нет информации, о самом объекте.

На самом деле зависит от django типа поля. В основном же объект нужно «доставать». Django может любые данные возвращать из валидатора.

А если нам нужно эту логику применять в другой вьюхе?

ООП же, нет?

cadogan
()
Ответ на: комментарий от pawnhearts

Да, только: 1. Note, however, that like Model.full_clean(), a model’s clean() method is not invoked when you call your model’s save() method.

Ну это ладно, переопределяем метод save и в нем вызываем self.full_clean().

2. Из-за вызова исключения ValidationError сервер выдает 500-ую ошибку. А хотелось бы 400-ую и с указанием поля с ошибкой и текстом ошибки (как это можно сделать в сериализатор и в форме).

hell_wood
() автор топика
Ответ на: комментарий от cadogan

Т.е делаем некий «миксин», в котором проходит эта бизнес логика (возможность создания объекта, вызов ошибки и т.п.). И этот миксион потом добавляем в качестве родителя, в разные вьюхи или сериализаторы?

hell_wood
() автор топика
Ответ на: комментарий от hell_wood

Зависит от программиста, я тут уже не помощник...

cadogan
()
Ответ на: комментарий от cadogan

Ну вот, например, в rest framework, когда мы кидаем в сериазаторе исключение ValidationError, то сервер возвращает 400-ую ошибку.

hell_wood
() автор топика

Сделай отдельный класс, в нём метод продать_нах(). Сделай класс-исключение НетВНаличии. Вызывай откуда хочешь, лови как надо.

anonymous
()
Ответ на: комментарий от hell_wood

А зачем тебе это в save? modelforms будут показывать ошибку как надо, drf тоже. В save валидации нет, оно вызывается когда данные уже проверены.

pawnhearts ★★★★★
()
Ответ на: комментарий от pawnhearts

Если это исключение вызываем в сериализаторе, то ошибка отображается как задумано, но это тогда нужно прописывать вызов исключения и в сериализаторе и в форме, т.е получается дублировать код. Идея была в том, чтобы подробную логику и генерацию ошибки перенести в одно место, для удобства опять же.

hell_wood
() автор топика
Ответ на: комментарий от hell_wood

Если ты будешь поднимать это исключение в model.clean оно будет у тебя подниматься и в drf и в формах.

pawnhearts ★★★★★
()

В такой постановке задачи — в триггере в базе если у тебя джанга запущена в 2+ треда/процесса/что-там-у-gevent'а. Для распределённых баз, впрочем, это сложнее. Хотя можно тупо lock поставить.

EDIT: в общем случае — ловить ошибку со стороны твоей БД.

нам уже в классе формы надо прописывать валидацию? Но это уже дублирование кода.

Нет, это не дублирование.

Если хочется бизнес-логику именно в джанге — это часто делается либо в модели, либо в отдельном слое бизнес-логики, который транслирует реальные события (продажа товара) в абстрагированную от реального мира БД, где уже меняется текущее количество на складе, в лучших традициях domain-driven design, вплоть до CQRS.

x3al ★★★★★
()
Последнее исправление: x3al (всего исправлений: 1)
Ответ на: комментарий от hell_wood

2. Из-за вызова исключения ValidationError сервер выдает 500-ую ошибку. А хотелось бы 400-ую и с указанием поля с ошибкой и текстом ошибки (как это можно сделать в сериализатор и в форме).

Ловить ошибки бизнес-логики и плеваться в пользователя юзерфрендли-сообщениями — задача view.

1. Note, however, that like Model.full_clean(), a model’s clean() method is not invoked when you call your model’s save() method.

Они вызываются когда ты делаешь clean/save у ModelForm.

x3al ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.