验证许多字段,因为它们是一个?

时间:2012-02-08 05:42:45

标签: python html forms google-app-engine wtforms

我的输入格式很奇怪,但根据规范:

enter image description here

用户应在4个字段(!)中输入ID,其中id为460 000 005 001,其中46是国家代码,右边部分是用户的appengine ID。现在我想在此字段中添加验证,但我无法使用wtforms进行验证。这是我的表单类:

class RegisterWTForm(Form):
    soc_sec = TextField(_('Soc security number'),  [validators.Regexp('^[0-9]+$',
                      message=_('This is not a social security number, please see the example and try again'
                      )), validators.Required(message=_('Social security number is required')), unique_soc_sec], widget=MyTextInput())
    email = TextField(_('Email'),
                      [validators.Required(message=_('Email is required'
                      )),
                      validators.Email(message=_('Your email is invalid'
                      ))], widget=MyTextInput())

    def validate_soc_sec(form, field):
        if len(field.data) != 10:
            raise ValidationError(_('Soc sec must be 10 characters'
                                  ))
    def validate_email(form, field):
        if len(field.data) > 60:
            raise ValidationError(_('Email must be less than 60 characters'
                                  ))

以下是我现在如何使用变量,它们不是WTForm的一部分,而是常规的http post参数:

def post(self):
    Log1 = self.request.POST.get('Log1')
    Log2 = self.request.POST.get('Log2')
    Log3 = self.request.POST.get('Log3')
    Log4 = self.request.POST.get('Log4')    
    form = RegisterWTForm(self.request.params)
    if form.validate():
        logging.info('validated successfully')
    else:
        logging.info('form did not validate')
        self.render_jinja('register.html', form=form, Log1=Log1, Log2=Log2, Log3=Log3, Log4=Log4 )
        return ''
    email = self.request.POST.get('email')

    sponsor_id = '%s%s%s' % (Log2, Log3, Log4)
    if sponsor_id:
        user = User.get_by_id(long(sponsor_id))
    else:
        return 'Sponsor with sponsor id %s does not exist' % sponsor_id
    if not user:
            return 'Sponsor with sponsor id %s does not exist' % sponsor_id

    # make a token for a one-time login link that sets the password
    # Passing password_raw=password so password will be hashed
    # Returns a tuple, where first value is BOOL. If True ok, If False no new user is created

    user = self.auth.store.user_model.create_user(email)

有没有办法将我的4个变量作为一个变量添加到我的WTForm并在那里添加验证,或者我应该为这些字段进行自己的自定义验证?对于我的其他字段,如果字段没有通过验证,我用红色边框和红色文本制作它们,我想在这里做同样的事情,但如果我不能,它会在表示层中有很多逻辑使用表单类执行此操作,并且必须将代码添加到模板中。你能建议做什么吗?

谢谢

更新

我可以创建一个FormField来组合字段,但它们无法正确呈现,我不需要全部4个验证。也许你可以告诉我更多如何以我想要的方式做到这一点?

class SponsorWTForm(Form):
    log1 = IntegerField('log1', [validators.required()])
    log2 = IntegerField('log2', [validators.required()])
    log3 = IntegerField('log3', [validators.required()])
    log4 = IntegerField('log4', [validators.required()])

class RegisterWTForm(Form):
    sponsor_id = FormField(SponsorWTForm)

...

enter image description here

1 个答案:

答案 0 :(得分:5)

看起来WTForms使用field enclosures解决了这个问题。该链接的示例是针对具有单独区号和号码字段字段的电话号码,这与您的多部分ID号用例非常相似。

要正确呈现子表单,您必须定义自定义小部件。看看the source code for ListWidget。您的小部件可能类似但更简单(因为我认为您只需要在不同字段之间留出空格,而不是HTML标记)。像

这样简单的东西
return HTMLString(u' '.join([subfield() for subfield in field]))

可能适合您的需求。然后将widget=SingleLineWidget()(或任何你命名的widget类)放在FormField构造函数的参数中。

稍微偏离主题,在Django Forms中执行此操作的相应方式有很大不同:您定义custom clean and validate methods转换数据(即在这种情况下,将4个ID字段合并为一个)。