【问题标题】:How to load a WTF Form class each time I hit an API endpoint每次点击 API 端点时如何加载 WTF 表单类
【发布时间】:2015-11-20 02:19:10
【问题描述】:

我正在使用 Flask WTF 表单,它依赖于从 API 加载供应商列表。这个供应商列表会改变,但是我发现每次我点击新项目路径时,(我希望重新创建 NewItemForm 类)旧类都是从内存中加载的。供应商 API 路径仅在对象创建时被点击一次

所以我将我的代码更新为这个非功能示例:我尽了最大努力,但我想做的是每次点击新库存项目路径时点击供应商 API 端点,当我创建 @987654321 @ 以便每次加载表单时供应商列表都会更改。我尝试通过创建一个方法来做到这一点。

解决这个问题的pythonic方法是什么?

api.py

@inventory.route('/inventory/new', methods=['GET', 'POST'])
def new_item():
    form = NewItemForm()
    form.update_vendors() 

form.py

from flask.ext.wtf import Form
from wtforms import StringField, SubmitField, SelectField, DecimalField, DateField
from wtforms.validators import Required, Length, NumberRange, Optional
from wtforms.widgets import TextArea
import requests, json, os

class NewItemForm(Form):
    def __init__(self):
        self.sorted_by_vendors=[('','')]

    def update_vendors(self):
        api_uri = os.environ.get('API_URL') or 'http://127.0.0.1/whiteboard_v2/v2/'
        second_url = api_uri + "api/vendors"
        second_request = requests.get(second_url)
        other_keys = second_request.json().keys()
        vendorOptions=[('','')]
        othersortedList = []
        for key in other_keys:
            vendor_tuple = (key, second_request.json()[key]['vendor_name'])
            vendorOptions.append(vendor_tuple)
            self.sorted_by_vendors = sorted(vendorOptions, key=lambda tup: (tup[1], tup[0]))

    vendor_code = SelectField('Vendor', choices = self.sorted_by_vendors, validators = [Required()])
    submit = SubmitField('Create Item')

如何在每次点击 new_item 端点时加载供应商列表,以便供应商下拉列表发生变化?

【问题讨论】:

  • 您实际上并没有在new_item 中调用update_vendors 方法。您需要添加() 来调用它:form.update_vendors()
  • 谢谢,但我很确定我的示例代码根本上是错误的。我只是用它来表明我的意图。
  • 意图似乎是正确的。你确定你第二次点击/new 路线吗?如果您这样做了,我会对来自原始请求的表单对象是否与第二个请求的表单对象相同感兴趣(也许 Flask 或 WTForms 试图巧妙地使用重用对象)。
  • 好吧,它在 vendor_code = SelectField('Vendor', choice = self.sorted_by_vendors, validators = [Required()]) 处完全出错,因为它无法识别自我。

标签: python python-3.x flask wtforms


【解决方案1】:

问题是您将字段与

绑定

vendor_code = SelectField('Vendor', choices = self.sorted_by_vendors, ...

类级别将字段的choices 属性绑定到对该列表的引用,然后您替换sorted_by_vendors 以引用新列表,而.choices 属性仍然指向旧的参考副本。

最简单的解决方法是在 update_vendors() 中进行此更改:

self.vendor_code.choices = sorted(vendorOptions, key=lambda tup: (tup[1], tup[0]))

你也可以把那个移出for循环,你只需要在最后做一次。

【讨论】:

    猜你喜欢
    • 2016-05-14
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-27
    • 1970-01-01
    相关资源
    最近更新 更多