【问题标题】:Google NDB model validation谷歌 NDB 模型验证
【发布时间】:2015-05-10 11:48:00
【问题描述】:

如何在 python 中验证 GAE 的 no sql "ndb" 模型?

是否有这种模式。假设我有一个名为 BreadCrumb 的模型

class BreadCrumb_Ndb(ndb.Model):
    """ A model for building breadcrumbs on the site """
    item_prop = ndb.StringProperty()
    item_type = ndb.StringProperty()
    href = ndb.StringProperty()

我想验证属性 href 以确保其使用正则表达式的 url 格式。

【问题讨论】:

  • 数据从何而来?表格?
  • 最终是的,它将来自一个表单。

标签: python google-app-engine google-cloud-datastore app-engine-ndb


【解决方案1】:

根据documentation,ndb 类型采用validator 参数,用于验证/强制属性的输入。但是,在尝试将提交的表单插入数据库之前验证提交的表单(因为这似乎是您打算做的)通常更明智(WTForms 非常适合这种用例)。

【讨论】:

  • 应该如何进行跨域验证?例如:模型有 start_date 和 end_date,我想确保 start_date 应该小于 end_date。
  • @akshar 我已经有一段时间没有使用引擎了,但根据我的回答,我相信validator 不是用于交叉验证,而只是类型/格式验证和必要时的强制.换句话说,您必须在插入数据库之前处理此问题。
【解决方案2】:

WTForms 可能正是您所需要的,因为它甚至会为您生成表单,然后在提交时检查它:

使用 WTForms,可以为您生成表单字段 HTML,但我们 让您在模板中自定义它。这使您可以保持 代码和表示分离,并保留那些杂乱无章的参数 出你的python代码。因为我们力求松耦合,所以您 也应该能够在您喜欢的任何模板引擎中做到这一点。 由于您的数据来自表单,您可以在 WTForms 在这里,您需要为 hrefs 添加自定义验证器:

class MyForm(Form):
    name = StringField('Name', [InputRequired()])

    def validate_name(form, field):
        if len(field.data) > 50:
            raise ValidationError('Name must be less than 50 characters')

现在支持 NDB:https://wtforms.readthedocs.org/en/1.0.4/ext.html

此答案中详细说明了另一种选择:Evaluate a condition after put() in NDB and GAE

您将在其中运行 post-put 挂钩进行验证。

【讨论】:

【解决方案3】:

正如另一个答案中提到的,ndb 属性子类接受 validator 参数。

验证和可能强制值的可选函数。

将使用参数 (prop, value) 调用并且应该返回 (可能是强制的)值或引发异常。调用 对强制值再次执行函数不应进一步修改该值。 (例如,返回 value.strip() 或 value.lower() 很好,但是 not value + '$'。)也可能返回 None,表示“没有变化”。

参考:https://cloud.google.com/appengine/docs/python/ndb/properties#options

最好在尽可能接近数据的地方应用您的验证。这将防止非表单数据输入任务破坏您的字段。类似的东西应该可以工作:

from urlparse import urlsplit
def is_url(prop, value):
    o = urlsplit(value)
    if not o.scheme or not o.netloc:
        raise Exception("{} is not a valid URL".format(value))
    return value

class BreadCrumb_Ndb(ndb.Model):
    """A model for building breadcrumbs on the site"""
    item_prop = ndb.StringProperty()
    item_type = ndb.StringProperty()
    href = ndb.StringProperty(validator=is_url)

【讨论】:

  • 应该如何进行跨字段验证?例如:模型有 start_date 和 end_date,我想确保 start_date 应该小于 end_date。
【解决方案4】:

如果需要跨字段验证,那么可能覆盖 put() 是最快的方法。

def put(self, *args, **kwargs):
    if self.start_date > self.end_date:
        raise Exception("start_date must be less than end_date")
    return super(BaseModel, self).put(*args, **kwargs)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-02
    • 2016-07-07
    • 2014-11-18
    • 2019-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多