问题描述
我有一个用户表单类:
class UserForm(Form):
first_name = TextField(u'First name', [validators.Required()])
last_name = TextField(u'Last name', [validators.Required()])
middle_name = TextField(u'Middle name', [validators.Required()])
username = TextField(u'Username', [validators.Required()])
password = TextField(u'Password', [validators.Required()], widget=PasswordInput())
email = TextField(u'Email', [validators.Optional(), validators.Email()])
并希望在 UpdateUserForm 中将密码字段设为可选:
and want to make the password field Optional in UpdateUserForm:
class UpdateUserForm(UserForm):
password = TextField(u'Password', [validators.Optional()], widget=PasswordInput())
但是密码字段放在电子邮件字段之后,而不是之前.
But the password field is placed after the email field, not before.
子类化时如何保留字段顺序?
How do I preserve field order when subclassing?
此外,当我尝试更改密码字段验证器时它不起作用 - 仍然需要密码:/为什么?
Additionally, when I try to change the password field validators it doesn't work - password still Required :/ Why?
class UpdateUserForm(UserForm):
def __init__(self, **kwargs):
self.password.validators = [validators.Optional()]
super(UpdateUserForm, self).__init__(**kwargs)
或
class UpdateUserForm(UserForm):
def __init__(self, **kwargs):
self.password = TextField(u'Password', [validators.Optional()], widget=PasswordInput())
super(UpdateUserForm, self).__init__(**kwargs)
一些想法...
class UpdateUserForm(UserForm):
def __init__(self, formdata=None, obj=None, prefix='', **kwargs):
self._unbound_fields[4][1] = TextField(u'Password', [validators.Optional()], widget=PasswordInput())
UserForm.__init__(self, formdata=None, obj=None, prefix='', **kwargs)
最后,我需要什么:
class UpdateUserForm(UserForm):
def __init__(self, formdata=None, obj=None, prefix='', **kwargs):
UserForm.__init__(self, formdata, obj, prefix, **kwargs)
self['password'].validators = [validators.Optional()]
self['password'].flags.required = False
推荐答案
关于在迭代表单对象时重新排列字段的第一个问题,我是这样做的:
In regards to your first question about reording the fields when iterating over the form object, this is what I did:
class BaseForm(Form):
def __iter__(self):
field_order = getattr(self, 'field_order', None)
if field_order:
temp_fields = []
for name in field_order:
if name == '*':
temp_fields.extend([f for f in self._unbound_fields if f[0] not in field_order])
else:
temp_fields.append([f for f in self._unbound_fields if f[0] == name][0])
self._unbound_fields = temp_fields
return super(BaseForm, self).__iter__()
class BaseUserForm(BaseForm):
password = PasswordField('Password', [Required()])
full_name = TextField('Full name', [Required()])
class NewUserForm(BaseUserForm):
username = Textfield('Username', [Required()])
field_order = ('username', '*')
这样,当您渲染 NewUserForm(可能来自一个逐个字段地遍历表单渲染字段的模板)时,您将看到 username
、password
、full_name
.通常,您会在最后看到 username
.
That way, when you render NewUserForm (perhaps from a template which iterates over the form rendering field by field), you'll see username
, password
, full_name
. Normally you'd see username
last.
这篇关于wtforms 表单类子类化和字段排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!