2012-06-29 2 views
2

Я вижу множество приложений, использующих объекты Form, для проверки данных, а затем передачи данных модели, в то же время абсолютно не проверяя модель. Я считаю, что лучше всего проводить проверку ядра в самой модели (например, без пользователей в возрасте до 18 лет), независимо от контекста. Другими словами, мне все равно, как создается пользователь (через веб-интерфейс или в командной строке), всегда должны применяться основные правила.Как поставить проверку формы в модели с помощью SQLAlchemy?

Я использую SQLAlchemy (в приложении Pyramid), и я хотел бы определить свои основные правила проверки в модели таким образом, чтобы мои формы (WTForms) всегда соблюдали основные правила, определенные в модели, так что все данные согласованы.

Кто-нибудь еще делает это или что-то подобное?

Нечто похожее на решение this php.

+0

Не могли бы вы переопределить все методы get/put/save/create, которые вы используете на своей модели в самом классе модели (поскольку они всегда должны иметь приоритет), а затем просто используйте 'super' для создания фактического создания/обновления если он проходит тесты? –

+1

Одна из причин, почему хорошо не ставить валидацию в модели, состоит в том, что у вас могут быть разные формы. Один забавный пример - сохранить неполную модель. Если вы попытаетесь сохранить неполную модель, ваша проверка модели не удастся, но если у вас есть валидация в ваших формах. Одна форма может провалиться или пройти, но конечный результат всегда будет действительным. Наличие валидации в моделях заставляет вас делать некоторые уродливые вещи, такие как условная валидация ... Имейте в виду, что модель не должна содержать никакой логики. –

+0

@ LoïcFaure-Lacroix Очень хороший момент, но я рассматриваю только основные правила, которые предотвращают сохранение неполной/поврежденной модели. Например, «каждый пользователь в базе данных должен иметь действительный возраст, никаких исключений». Я чувствую, что правило с таким важным значением должно находиться в модели и служить в качестве окончательной стены обороны, если хотите. – BDuelz

ответ

2

SQLAlchemy позволяет регистрировать слушателей, которые вызывают при возникновении определенных событий, например, вы можете зарегистрировать событие, которое будет инициировано при изменении поля модели. Из SQLAlchemy documentation:

Слушатели имеют возможность возвращать, возможно, модифицированную версию значения , когда RetVal = True передается флаг слушать():

def validate_phone(target, value, oldvalue, initiator): 
    "Strip non-numeric characters from a phone number" 

    return re.sub(r'(?![0-9])', '', value) 

# setup listener on UserContact.phone attribute, instructing 
# it to use the return value 
listen(UserContact.phone, 'set', validate_phone, retval=True) 

Функция проверки, как выше также может вызвать исключение, такое как , как ValueError, чтобы остановить операцию.

Таким образом, как вы видите, вы можете изменять или отклонять значения для определенного поля на уровне модели.

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

+2

Как насчет [@validates] (http://docs.sqlalchemy.org/en/rel_0_9/orm/mapper_config.html#simple-validators)? – Zitrax

+0

@Zitrak: ссылка изменилась, теперь это http://docs.sqlalchemy.org/en/rel_0_9/orm/mapped_attributes.html#simple-validators – runejuhl

Смежные вопросы