wtforms 表单类子类化和字段排序 [英] wtforms Form class subclassing and field ordering

查看:30
本文介绍了wtforms 表单类子类化和字段排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用户表单类:

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(可能来自一个逐个字段地遍历表单渲染字段的模板)时,您将看到 usernamepasswordfull_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 表单类子类化和字段排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆