Разделение ORM и валидация - PullRequest
0 голосов
/ 10 июля 2009

Я использую django и мне интересно, в каких случаях должна проходить валидация модели. Есть как минимум два варианта:

  1. Подтвердить в методе сохранения модели и вызвать IntegrityError или другое исключение, если бизнес-правила были нарушены
  2. Проверка данных с использованием форм и встроенных средств clean_ *

С одной точки зрения ответ очевиден: нужно использовать валидацию на основе форм. Это потому, что ORM - это ORM, а валидация - совершенно другая концепция. Взгляните на CharField: forms.CharField разрешает спецификацию min_length, но models.CharField этого не делает. Хорошо, круто, но что, черт возьми, все эти функции проверки делают в django.db.models? Я могу указать, что CharField не может быть пустым, я могу использовать EmailField, FileField, проверка SlugField которых выполняется здесь, в python, а не в RDBMS. Кроме того, есть URLField, который проверяет существование URL-адреса, включающего некоторую действительно сложную логику.

С другой стороны, если у меня есть сущность, я хочу гарантировать, что она не будет сохранена в несогласованном состоянии, независимо от того, пришла она из формы или была изменена / создана некоторыми внутренними алгоритмами. У меня есть модель с полем имени, я ожидаю, что она должна быть длиннее, чем один символ. У меня также есть поля min_age и max_age, это не имеет большого смысла, если min_age> max_age. Так я должен проверить такие условия в методе сохранения?

Каковы лучшие практики проверки моделей?

Ответы [ 5 ]

0 голосов
/ 10 июля 2009

БД / Проверка модели

Хранилище данных в базе данных всегда должно быть в определенной форме / состоянии. Например: требуется имя, фамилия, внешний ключ, ограничение уникальности. Это где логика вашего приложения находится. Независимо от того, откуда, по вашему мнению, поступают данные - их следует «проверить» и создать исключение, если требования не выполняются.

Проверка формы

Вводимые данные должны выглядеть вправо. Это нормально, если эти данные вводятся по-другому с помощью других средств (через вызовы администратора или API). Примеры: длина имени человека, правильная капитализация предложения ...

Example1 : Объект имеет StartDate и EndDate . StartDate всегда должно быть раньше EndDate . Где вы подтверждаете это? В модели конечно! Рассмотрим случай, когда вы можете импортировать данные из другой системы - вы не хотите, чтобы это проходило.

Example2 : подтверждение пароля. У вас есть поле для хранения пароля в БД. Однако вы отображаете два поля: пароль1 и пароль2 в вашей форме. Форма и только форма отвечает за сравнение этих двух полей, чтобы убедиться, что они одинаковы. После того, как форма верна, вы можете безопасно сохранить поле password1 в БД в качестве пароля.

0 голосов
/ 10 июля 2009

"но что, черт возьми, все эти функции проверки делают в django.db.models?"

Одно слово: Наследие. Ранние версии Django имели менее надежные формы, и проверка была разбросана.

«Так я должен проверить такие условия в методе сохранения?»

Нет, вы должны использовать форму для всей проверки.

«Каковы лучшие методы проверки моделей?» *

Используйте форму для всей проверки.

"пришло ли оно из формы или было изменено / создано некоторыми внутренними алгоритмами"

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

В противном случае внутренне сгенерированные данные по определению действительны. Только пользовательские данные могут быть недействительными. Если вы не доверяете своему программному обеспечению, какой смысл его писать? Ваши юнит-тесты сломаны?

0 голосов
/ 10 июля 2009

Ваши два варианта - это две разные вещи.

  • Проверка на основе форм может рассматриваться как синтаксическая проверка + преобразование параметров HTTP-запроса из текста в типы Python.
  • Проверка на основе модели может рассматриваться как семантическая проверка, иногда с использованием контекста, недоступного на уровне HTTP / формы.

И, конечно, в БД существует третий уровень, где ограничения применяются, и их нельзя проверять где-либо еще из-за одновременных запросов на обновление базы данных (например, ограничения уникальности, оптимистическая блокировка).

0 голосов
/ 10 июля 2009

В настоящее время существует проект Google Summer of Code, целью которого является проверка на уровне модели Django. Вы можете прочитать больше об этом в этой презентации от студента GSoC (Хонза Краль). Также имеется репозиторий github с предварительным кодом.

До тех пор, пока этот код не попадет в релиз Django, рекомендуется использовать ModelForms для проверки данных, даже если источник не является формой. Это описано в этой записи в блоге от одного из разработчиков ядра Django.

0 голосов
/ 10 июля 2009

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

Вы также можете попробовать вставить ограничения размера с помощью ** kwargs в функцию проверки, которая вызывается перед вызовом put ().

...