如何在 WTForms 中使字段有条件地可选? [英] How to make a field conditionally optional in WTForms?

查看:36
本文介绍了如何在 WTForms 中使字段有条件地可选?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的表单验证工作几乎完成,我只有两种情况我不知道如何解决:1) 当然应该需要密码字段,但我也提供了使用 google 或 facebook 帐户登录的可能性通过 OAuth,然后名称被预填充,但我从表单中完全删除密码字段是否有用户(谷歌)或 Facebook 用户对象:

<br/>{% if user 或 current_user %} {% else %}<div class="labelform">{% filter capitalize %}{% trans %}password{% endtrans %}{% endfilter %}:

</td><td><div class="adinput">{{ form.password|safe }}{% trans %}选择密码{% endtrans %}

{% endif %}</td></tr>

所以对于这些已经登录并且密码字段没有意义的用户,我需要一些逻辑来使该字段有条件地可选.我在想我可以在我的表单类中有一个用于 login_in 的变量 + 一个方法,例如:

class AdForm(Form):登录 = 假my_choices = [('1', _('VEHICLES')), ('2', _('Cars')), ('3', _('Bicycles'))]name = TextField(_('Name'), [validators.Required(message=_('Name is required'))], widget=MyTextInput())title = TextField(_('title'), [validators.Required(message=_('Subject is required'))], widget=MyTextInput())text = TextAreaField(_('Text'),[validators.Required(message=_('Text is required'))], widget=MyTextArea())phonenumber = TextField(_('电话号码'))phoneview = BooleanField(_('在网站上显示电话号码'))price = TextField(_('Price'),[validators.Regexp('d', message=_('这不是一个整数,请看例子再试')),validators.Optional()])password = PasswordField(_('Password'),[validators.Optional()], widget=PasswordInput())email = TextField(_('Email'), [validators.Required(message=_('Email is required')), validators.Email(message=_('您的电子邮件无效'))], widget=MyTextInput())类别 = SelectField(选择 = my_choices,默认 = '1')def validate_name(form, field):如果 len(field.data) >50:raise ValidationError(_('名称必须少于 50 个字符'))def validate_email(表单,字段):如果 len(field.data) >60:raise ValidationError(_('电子邮件必须少于 60 个字符'))def validate_price(form, field):如果 len(field.data) >8:raise ValidationError(_('价格必须小于 9 个整数'))def validate_password(表单,字段):如果没有登录并且没有字段:引发 ValidationError(_('需要密码'))

上面的validate_password 能达到预期的效果吗?还有其他更好的方法吗?我能想到的另一种方法是拥有 2 个不同的表单类,并在 http 帖子中实例化它应该是的表单类:

def post(self):如果不是 current_user:form = AdForm(self.request.params)如果当前用户:form = AdUserForm(self.request.params)

I also need conditional validation for the category field, when a certain category is selected then more choices appear and these should have validation only for a certain base-category eg.用户选择汽车",然后通过 Ajax 可以选择汽车的注册数据和里程,如果选择了类别汽车,这些字段是必需的.

所以这可能是两个问题,但这两种情况都与我如何使字段有条件可选"或有条件要求"有关.

我的表格是这样的

对于登录用户,我预先填写了姓名和电子邮件地址,并且根本不使用密码字段,因此密码字段既不适合可选"也不适合必需",它需要诸如有条件可选"或有条件地需要."

感谢您的任何回答或评论

解决方案

我不确定这是否完全符合您的需求,但我之前在字段上使用了 RequiredIf 自定义验证器,这使得如果另一个字段在表单中具有值,则需要一个字段...例如,在日期时间和时区场景中,如果用户输入了日期时间,我可以使时区字段需要具有值.

class RequiredIf(Required):# 一个验证器,它使一个字段成为必需的 if# 另一个字段被设置并有一个真值def __init__(self, other_field_name, *args, **kwargs):self.other_field_name = other_field_namesuper(RequiredIf, self).__init__(*args, **kwargs)def __call__(self, form, field):other_field = form._fields.get(self.other_field_name)如果 other_field 为 None:引发异常('表单中没有名为%s"的字段'%self.other_field_name)如果布尔(other_field.data):super(RequiredIf, self).__call__(form, field)

构造函数采用触发此字段的其他字段的名称,例如:

class DateTimeForm(Form):日期时间 = TextField()timezone = SelectField(choices=..., validators=[RequiredIf('datetime')])

这可能是实现您需要的那种逻辑的一个很好的起点.

My form validation is working nearly complete, I just have 2 cases I don't know exactly how to solve: 1) The password field should be required of course but I also provide the possibility to log in with google or facebook account via OAuth and then name gets prefilled but I remove the password field completely from the form is there is a user (google) or a facebook user object:

<tr><td>
  <br />        {% if user or current_user %}    {% else %} 

  <div class="labelform">
     {% filter capitalize %}{% trans %}password{% endtrans %}{% endfilter %}:
  </div>
      </td><td>  <div class="adinput">{{ form.password|safe }}{% trans %}Choose a password{% endtrans %}</div>{% endif %}

  </td></tr>

So for these users who already are logged in and the password field has no meaning, I need some logic to make that field conditionally optional. I was thinking that I could have a variable for logged_in + a method in my form class such as this:

class AdForm(Form):
    logged_in = False
    my_choices = [('1', _('VEHICLES')), ('2', _('Cars')), ('3', _('Bicycles'))]
    name = TextField(_('Name'), [validators.Required(message=_('Name is required'))], widget=MyTextInput())
    title = TextField(_('title'), [validators.Required(message=_('Subject is required'))], widget=MyTextInput())
    text = TextAreaField(_('Text'),[validators.Required(message=_('Text is required'))], widget=MyTextArea())
    phonenumber = TextField(_('Phone number'))
    phoneview = BooleanField(_('Display phone number on site'))
    price = TextField(_('Price'),[validators.Regexp('d', message=_('This is not an integer number, please see the example and try again')),validators.Optional()] )
    password = PasswordField(_('Password'),[validators.Optional()], widget=PasswordInput())
    email = TextField(_('Email'), [validators.Required(message=_('Email is required')), validators.Email(message=_('Your email is invalid'))], widget=MyTextInput())
    category = SelectField(choices = my_choices, default = '1')

    def validate_name(form, field):
        if len(field.data) > 50:
            raise ValidationError(_('Name must be less than 50 characters'))

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

    def validate_price(form, field):
        if len(field.data) > 8:
            raise ValidationError(_('Price must be less than 9 integers'))

    def validate_password(form, field):
        if not logged_in and not field:
            raise ValidationError(_('Password is required'))

Will the above validate_password work to achieve the desired effect? Is there another better way? Another way I could think is to have 2 different form class and in http post I instanciate the form class it should be:

def post(self):
    if not current_user:
      form = AdForm(self.request.params)
    if current_user:
      form = AdUserForm(self.request.params)

I also need conditional validation for the category field, when a certain category is selected then more choices appear and these should have validation only for a certain base-category eg. user selects "Car" and then via Ajax can choose registration data and mileage for the car and these fields are required given that the category Car was selected.

So it might be two questions but both cases relate to how I can make a field "conditionally optional" or "conditionally required".

My form looks like this

And for a logged in user I prefill the name and email address and the pasword field is simply not used, so the password field neither fits being "optional" nor "required", it would need something like "conditionally optional" or "conditionally required."

Thanks for any answer or comment

解决方案

I'm not sure this quite fits your needs, but I've used a RequiredIf custom validator on fields before, which makes a field required if another field has a value in the form... for instance, in a datetime-and-timezone scenario, I can make the timezone field required to have a value if the user has entered a datetime.

class RequiredIf(Required):
    # a validator which makes a field required if
    # another field is set and has a truthy value

    def __init__(self, other_field_name, *args, **kwargs):
        self.other_field_name = other_field_name
        super(RequiredIf, self).__init__(*args, **kwargs)

    def __call__(self, form, field):
        other_field = form._fields.get(self.other_field_name)
        if other_field is None:
            raise Exception('no field named "%s" in form' % self.other_field_name)
        if bool(other_field.data):
            super(RequiredIf, self).__call__(form, field)

The constructor takes the name of the other field that triggers making this field required, like:

class DateTimeForm(Form):
    datetime = TextField()
    timezone = SelectField(choices=..., validators=[RequiredIf('datetime')])

This could be a good starting point for implementing the sort of logic you need.

这篇关于如何在 WTForms 中使字段有条件地可选?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
Python最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆