- Хроники. - -
AppEngine валидация полей базы и формы
Posted By Ikutsin On 2 апреля 2010 @ 14:39 In Python | Comments Disabled
[1]Как и в Django, валидацию для полей AppEngine Datastore можно сделать на нескольких уровнях. Лучший способ проверить соответствие объекта правилам — использовать FormModel.is_valid(), которая очистить и проверит поля на уровне класса формы (clean) и полей базы (Property.validate), но обо всем по порядку.
Статья ни в коем случае не претендует на полноту изложенного, я просто делюсь опытом изучения AppEngine и Python.Стандартный способ деления на уровни в Django, заключается в создании модели, формы на модель и шаблона. Предположим, что у нас есть следующая модель и форма для комментариев:
class Comment(db.Model): content = db.StringProperty() isContra = db.BooleanProperty() topic = db.ReferenceProperty(Topic) owner = db.ReferenceProperty(User) class CommentForm(djangoforms.ModelForm): class Meta: model = Comment
Опустим topic и owner. А остановимся на поле content.
Класс Property [2] в конструкторе может получить функцию в параметр validator. Используем этот способ вместе с Питоновской особенностью создавать вызываемые классы:
class Length(): def __init__(self, min, max): self.min = min self.max = max def __call__(self, value): if not (self.min <= len(value) <= self.max): raise BadValueError("%s <= len(%s) <= %s" % (self.min, value, self.max)) class Range(): def __init__(self, min, max): self.min = min self.max = max def __call__(self, value): if not (self.min <= value <= self.max): raise BadValueError("%s <= %s <= %s" % (self.min, value, self.max)) class Regex(): def __init__(self, regex): self.rregex = re.compile(regex) def __call__(self, value): if not self.rregex.match(value): raise BadValueError("Regex failure:") class Email(Regex): def __init__(self): Regex.__init__(self, "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}$")
Теперь один из классов можно подключить так: content = db.StringProperty(validator=Length(0,500))
Это стандартный способ проверки форм в Django [3]. Он заключается в добавлении методов clean_<поле> и изменения значения или возбуждения исключения:
def clean_сontent(self): content= self.clean_data['content'] vldt = Length(0,10) vldt(content) return content
или
</pre> def clean_сontent(self): content= self.clean_data['content'] return content[0:10]
Так как поле content подразумевает что его вводит посетитель сайта, это обозначает что туда может попасть не совсем то, что подразумевалось. Например XSS. Самый простой способ этого избежать — это безжалостно вырезать все теги.
Судя по примерам в интернете, поле сохраняется без изменения а фильтруется во время вывода на страницу (например в шаблоне). Лично я слишком ленивый, чтобы помнить о том, что должно фильтроваться. Да и с точки зрения архитектуры. я не уверен что фильтрация должна перекладываться на плечи дизайнера.
По этому, я использую новый тип поля: content = db.HtmlFreeProperty(validator=Length(0,500))
, следующей реализации:
class HtmlFreeStringProperty(db.StringProperty): def validate(self, value): value = strip_tags(value) return super(HtmlFreeStringProperty, self).validate(value)
Независимо от того, какой способ определения поведения модели выбран, проверить ее можно с помощью метода формы is_valid(). Детали подробно описаны в документации по использованию форм в AppEngine [4].
Article printed from Хроники.:
URL to article: /1374-appengine-validaciya-polej-bazy-i-formy
URLs in this post:
[1] Image: /wp-content/uploads/2010/04/appeng.png
[2] Property: http://code.google.com/intl/ru/appengine/docs/python/datastore/propertyclass.html
[3] способ проверки форм в Django: http://docs.djangoproject.com/en/dev/ref/forms/validation/
[4] использованию форм в AppEngine: http://code.google.com/intl/ru/appengine/articles/djangoforms.html
Click here to print.
Copyright © 2008 Все, что меня окружает. All rights reserved.