动态更改SelectField和HiddenField之间的WTForms字段类型 [英] Dynamically change WTForms field type between SelectField and HiddenField

查看:1038
本文介绍了动态更改SelectField和HiddenField之间的WTForms字段类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WTForms字段(value_currency),我想有时是一个SelectField,有时候是一个HiddenField。我使用相同的视图和模板来创建新项目和编辑现有项目的页面。如果我加载页面来创建一个新项目,我希望这个字段是一个SelectField,如果我加载页面来编辑一个现有的项目,我希望这个字段是一个HiddenField,因为它是一个不可编辑的字段。



pre> 类PromoForm(Form):
value = StringField('value')
currency = Currency.query.order_by(Currency.id).all()
currency_choices = []
以货币为单位:
currency_choice =(currency.id,currency.name)
currency_choices.append(currency_choice)
value_currency = SelectField('




$ b














  @ app.route('/ promo /< id>',methods = ['GET','POST'])
@login_required
def promo (id):
form = PromoForm()
#如果要创建一个新的促销,$现有的促销将通过它的ID
#id = 0
if id!= str(0):
#加载现有的促销
promo = Promo.query.get(id)
以十进制格式显示值
form.value格式(
promo.value_cents // 100,promo.value_cents%100)
form.process()
返回格式(.default ={0}。{1:0& render_template('promo.html',promo = promo,form = form)
else:
#new promo
audit_log('GET',client,session = session)
return render_template('promo.html',form = form)

TEMPLATE

  {%extendsbase.html%} 
{%block content%}
{%if promo is defined%}
< form action ={{url_for('。promo',id = promo.id)}}method =post>
{%else%}
{%endif%}
{{form.hidden_​​tag()}}
< div>
< label for =value>促销价值< / label>
{%if promo is defined%}
{{form.value()}}
{%else%}
{{form.value()}}
{%endif%}
{%for form.value.errors%中的错误}
< span class =error> [{{error}}]< / span>
{%endfor%}
{%if promo is defined%}
#----> Promo.value_currency在这里应该是一个隐藏字段(不起作用)
{{promo.value_currency}}
{%else%}
#----> Promo.value_currency是这里的一个选择字段(当前有效)
{{form.value_currency()}}
{%endif%}
< / div>
< div class =submit_btn>
{%if promo is defined%}
< input type =submitvalue =Update Promo>
{%else%}
< input type =submitvalue =Create Promo>
{%endif%}
< / div>
{%endblock%}

我知道我可以简单地硬编码隐藏的输入元素,与Jinja的价值下降,但我更喜欢用WTForms做,而不是做任何形式元素的硬编码。是否有可能?

解决方案

请参阅(重复)问题: Flask,WTForms:有没有一种方法可以隐藏窗体_visiblerily_中的StringField ?



您不能仅仅忽略 字段,也不能将其对象类型(从SelectField更改为HiddenField)。但是,您可以动态更改其 widget 对象。
用wtforms替换为 HiddenInput

 。 Widgets import HiddenInput 
$ b $ class PromoForm(Form):
value = StringField('value')
currency = Currency.query.order_by(Currency.id).all()
currency_choices = []
以货币为单位:
currency_choice =(currency.id,currency.name)
currency_choices.append(currency_choice)
value_currency = SelectField(' value_currency',choices = currency_choices)

def hide_value_currency(self,value):

将value_currency字段变成
HiddenInput。

self.value_currency.widget = HiddenInput()
#wtforms扼流器如果数据属性不存在
self.value_currency.data = value
#wtforms在带有HiddenInput小部件的SelectField上扼流器
#如果没有_data()可调用
self.value_currency._value = lambda:value

调用 form.hide_value_currency(pre_set_value )



您的模板中没有必要的逻辑。


I have a WTForms field (value_currency) that I want to sometimes be a SelectField and sometimes a HiddenField. I use the same view and template for a page that both creates new items and edits existing items. If I load the page to create a new item, I want this field to be a SelectField, and if I load the page to edit an existing item, I want this field to be a HiddenField because it's a non-editable field.

Here is what I have so far:

FORM

class PromoForm(Form):
    value = StringField('value')
    currencies = Currency.query.order_by(Currency.id).all()
    currency_choices = []
    for currency in currencies:
        currency_choice = (currency.id, currency.name)
        currency_choices.append(currency_choice)
    value_currency = SelectField('value_currency', choices=currency_choices)

VIEW

@app.route('/promo/<id>', methods=['GET', 'POST'])
@login_required
def promo(id):
    form = PromoForm()
    # Existing promo will pass in its id
    # id = 0 if a new promo is to be created
    if id != str(0):
        # Load existing promo
        promo = Promo.query.get(id)
        # display value in decimal format
        form.value.default = "{0}.{1:0>2}".format(
            promo.value_cents//100, promo.value_cents%100)
        form.process()
        return render_template('promo.html', promo=promo, form=form)
    else:
        # New promo
        audit_log('GET', client, session=session)
        return render_template('promo.html', form=form)

TEMPLATE

{% extends "base.html" %}
{% block content %}
    {% if promo is defined %}
        <form action="{{ url_for('.promo', id=promo.id) }}" method="post">
    {% else %}
        <form action="{{ url_for('.promo', id=0) }}" method="post">
    {% endif %}
    {{ form.hidden_tag() }}
    <div>
        <label for="value">Promo Value</label>
        {% if promo is defined %}
            {{ form.value() }}
        {% else %}
            {{ form.value() }}
        {% endif %}
        {% for error in form.value.errors %}
            <span class="error">[{{ error }}]</span>
        {% endfor %}
        {% if promo is defined %}
            # ----> Promo.value_currency should be a hidden field here (Doesn't work)
            {{ promo.value_currency }}
        {% else %}
            # ----> Promo.value_currency is a select field here (Currently works)
            {{ form.value_currency() }}
        {% endif %}
    </div>
    <div class="submit_btn">
        {% if promo is defined %}
            <input type="submit" value="Update Promo">
        {% else %}
            <input type="submit" value="Create Promo">
        {% endif %}
    </div>
{% endblock %}

I know I can just simply hardcode the hidden input element and drop in the value with Jinja, but I prefer to do it with WTForms and not do any form element hard coding. Is that possible?

解决方案

See (duplicated) question: Flask, WTForms: Is there a way to make a StringField in the form _temporarily_ hidden?.

You cannot just omit the field, and you cannot change its object type (from SelectField to HiddenField) neither.

However, you can change its widget object dynamically. Replace this with a HiddenInput.

from wtforms.widgets import HiddenInput

class PromoForm(Form):
    value = StringField('value')
    currencies = Currency.query.order_by(Currency.id).all()
    currency_choices = []
    for currency in currencies:
        currency_choice = (currency.id, currency.name)
        currency_choices.append(currency_choice)
    value_currency = SelectField('value_currency', choices=currency_choices)

    def hide_value_currency(self, value):
        """
        Hide the value_currency field by morping it into a 
        HiddenInput.    
        """ 
        self.value_currency.widget = HiddenInput()
        # wtforms chokes if the data attribute is not present
        self.value_currency.data = value
        # wtforms chokes on SelectField with HiddenInput widget
        # if there is no _data() callable
        self.value_currency._value = lambda: value

Call form.hide_value_currency(pre_set_value) in your view when required.

No logic in your template necessary.

这篇关于动态更改SelectField和HiddenField之间的WTForms字段类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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