我的输入格式很奇怪,但根据规范:
用户应在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)
...
答案 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字段合并为一个)。