Python AppEngine,EmailProperty 不能为空

Python AppEngine, EmailProperty cannot be blank

我正在使用 Flask 构建基于表单的应用程序,运行 遇到了可选电子邮件字段的问题。

是否有任何方法可以设置 EmailProperty() 类型的数据存储区字段并允许其为空?似乎即使在实体定义中使用 required=False,它仍然会引发 BadValueError 表示字段 must not be empty.

# my entity definition
from google.appengine.ext import db

class Model(db.Model):
    email = db.EmailProperty(required=False)

最近几个版本的Python客户端,在google_appengine/google/appengine/api/datastore_types.py第879行左右,Emailclass的__init__调用是这样的:

class Email(unicode):
    def __init__(self, email):
        super(Email, self).__init__()
        ValidateString(email, 'email')

它将执行传递给 ValidateString,它有一个 empty_ok 布尔参数,默认为 False:

def ValidateString(value,
                   name='unused',
                   exception=datastore_errors.BadValueError,
                   max_len=_MAX_STRING_LENGTH,
                   empty_ok=False):

如果 get 设置为与我的 EmailProperty 字段的 required= 参数设置相反的值,那就太好了。例如,在我的实体定义中,因为我有 required=False 如果此电子邮件 class 可以在调用 [=26= 时将 True 传递到 empty_ok 参数中,那就太好了].但是,既然没有,我真的很想找出一个好的解决方法。

我不可能是唯一一个曾尝试存储可选电子邮件地址字段的开发人员吗?如果数据在我的表单上传递,我仍然希望内置验证为 运行,所以我不想更改为 StringProperty 如果我可以帮助它...

如果提供了电子邮件,只调用验证函数怎么样?

class Email(unicode):
    def __init__(self, email):
        super(Email, self).__init__()
        if email != "":
            ValidateString(email, 'email')

请注意,我故意选择 if email != "" 而不是更像 pythonic 的 if email,这样如果用户提供一个非空的 "email",其计算结果为 False , 它不会导致跳过字符串验证。

N.B.:db 模块早已被 ndb 模块取代。 db 多年来没有收到任何重大更新。我真的建议尽可能更新,但尽管如此,这里还是有一些解决方法。

正如您所确定的,Email class 不允许空值。可能在这里做的最简单的事情就是定义你自己的类型 class 和 属性 class 来代替 EmailProperty:

    from google.appengine.ext import db


    class EmailOrNone(datastore_types.Email):
        def __init__(self, email):
            super(EmailOrNone, self).__init__(email)
            ValidateString(email, 'email', empty_ok=True)


    class EmailOrNoneProperty(db.EmailProperty):
        data_type = EmailOrNone

然后只需使用新的 EmailOrNoneProperty 代替 EmailProperty

您也可以只使用 StringPropertycustom validator

免责声明:我没有测试过这段代码,但这个想法是正确的。