2015-09-04 34 views
3

我有一個WTForms字段(value_currency),我希望它有時可以是SelectField,有時也可以是HiddenField。我爲同時創建新項目和編輯現有項目的頁面使用相同的視圖和模板。如果我加載頁面來創建一個新項目,我希望這個字段是一個SelectField,如果我加載頁面來編輯一個現有的項目,我希望這個字段是一個HiddenField,因爲它是一個不可編輯的字段。動態更改SelectField和HiddenField之間的WTForms字段類型

這是我到目前爲止有:

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) 

模板

{% 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 %} 

我知道我可以只是簡單的硬編碼的隱藏輸入的Elemen t並降低與Jinja的價值,但我更喜歡用WTForms來做,而不是做任何形式元素的硬編碼。那可能嗎?

+0

爲什麼不在編輯記錄時忽略模板中的字段? – dirn

+0

看來WTForms不喜歡這樣,因爲它是表單的一部分。當我這樣做時,表單頁面只會刷新提交和form.validate_on_submit == False,所以更新不會得到處理。 –

回答

1

查看(重複)的問題:Flask, WTForms: Is there a way to make a StringField in the form _temporarily_ hidden?

你不能只是忽略這個字段,你也不能改變它的對象類型(從SelectField到HiddenField)。

但是,您可以動態更改其小部件對象對象。 將其替換爲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 

需要時在您的視圖中致電form.hide_value_currency(pre_set_value)

模板中沒有必要的邏輯。

相關問題