本文介绍了动态更改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做,而不是做任何形式元素的硬编码。是否有可能?

解决方案

请参阅(重复)问题:。



您不能仅仅忽略 字段,也不能将其对象类型(从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字段类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-21 03:06