Formencode忽略USPostalCode上的if_missing

时间:2017-06-06 10:45:10

标签: validation pyramid formencode

我遇到FormEncode没有确认验证器设置了if_missing的问题。它不断返回字段的“Missing Error”错误。

我有一个看起来像这样的架构

class ABCSchema(Schema):

allow_extra_fields = True
filter_extra_fields = True

primary_surname = validators.UnicodeString(not_empty=True)
mailing_address_1 = validators.UnicodeString(not_empty=True)
mailing_address_2 = validators.UnicodeString()
mailing_city = validators.UnicodeString(not_empty=True)
mailing_state = national.USStateProvince(not_empty=True)
mailing_zip = national.USPostalCode(not_empty=True) 
billing_address_is_same_as_mailing = validators.StringBool(if_empty=False, not_empty=False)
billing_address_1 = validators.UnicodeString(if_missing=None)
billing_address_2 = validators.UnicodeString(if_missing=None)
billing_city = validators.UnicodeString(if_missing=None)
billing_state = national.USStateProvince(if_missing=None)
billing_zip = national.USPostalCode(if_empty=None, not_empty=False)
special_instructions = validators.UnicodeString()

有问题的验证器是billing_zip。

这个想法是用户可以选择翻转billing_address_is_same_as_mailing标志。这将禁用帐单地址字段,以防止提交这些字段。

提交表单后,请求具有以下值

NestedMultiDict([('primary_surname', 'Something'), ('mailing_address_1', '81 turnbull St'), ('mailing_address_2', ''), ('mailing_city', 'Tampa'), ('mailing_state', 'NE'), ('mailing_zip', '98754'), ('billing_address_is_same_as_mailing', 'True'), ('special_instructions', ''), ('submit', 'Submit')])

使用以下数据和错误字符进行验证。

{'special_instructions': '', 'billing_city': None, 'mailing_city': 'Budd Lake', 'primary_surname': 'Something', 'billing_address_is_same_as_mailing': 'True', 'billing_state': None, 'mailing_address_1': '81 turnbull St', 'billing_zip': None, 'mailing_zip': '07828', 'mailing_state': 'NE', 'billing_address_2': None, 'submit': 'Submit', 'billing_address_1': None, 'mailing_address_2': '8 Locust St'}
{'billing_zip': 'Missing value'}

我尝试了各种组合中的if_empty,if_missing和not_empty,但如果缺少billing_zip,我似乎无法通过验证器。但是,它似乎没有抱怨其他结算字段。

我错过了什么?

1 个答案:

答案 0 :(得分:1)

USPostalCode确实忽略了if_missing选项。可以在源代码中看到(USPostalCode实现为Any复合验证器,与All复合验证器不同,不定义if_missing。接下来的命令也证明了这一点:

>>> validators.Regex(r'^\d+$', not_empty=False, if_missing='').if_missing
''
>>> national.USPostalCode(not_empty=False, if_missing='').if_missing
<class 'formencode.api.NoDefault'>

这应该是formencode中的一个错误。

作为一种可能的解决方法,可以为每个验证器手动定义if_missing

us_postal_code_validator = national.USPostalCode(if_empty=None, not_empty=False)
us_postal_code_validator.if_missing = ''

class ABCSchema(Schema):
    allow_extra_fields = True
    filter_extra_fields = True
    billing_zip = us_postal_code_validator

或者可以为整个模式定义if_key_missing(但要小心,因为它会影响该模式中的所有字段):

class ABCSchema(Schema):
    if_key_missing = ''
    allow_extra_fields = True
    filter_extra_fields = True
    billing_zip = national.USPostalCode(if_empty=None, not_empty=False)