- Хроники. - -

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)

FormModel.is_valid()

Независимо от того, какой способ определения поведения модели выбран, проверить ее можно с помощью метода формы 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

Copyright © 2008 Все, что меня окружает. All rights reserved.