【问题标题】:pass data from view to form as choices将数据从视图传递到表单作为选择
【发布时间】:2014-05-12 14:31:24
【问题描述】:

不明白如何将从form.data 获得的数据作为choices 传递到表单字段。非常感谢任何帮助。

所以,这就是我正在做的事情:我使用页面上的复选框选择数据,然后我需要在同一页面上显示所选数据(它们的名称),每个页面附近都有额外的文本字段。稍后必须填写所有文本字段,并且必须将“名称”和插入的数据发送到服务器。

据我了解,我需要使用表单在文本字段中呈现数据。我想可能是这个:

forms.py

import methods

class MultiTextField(SelectMultipleField):
    widget = widgets.TableWidget()
    option_widget = widgets.TextInput()

class SelectedForm(Form):
    choices = methods.selected()
    value = MultiTextField('value',choices = choices)

views.py

from forms import ...

selected_data = {}

def return_selected():
    return selected_data

methods.py

from views import return_selected

def selected():
    data = return_selected()
    choices = []
    for key, value in data.iteritems():
        for item in value:
            choices.append((item, key))
    return choices

变量selected_data 存储通过其他形式选择的数据。

如果我运行此代码,我会收到错误 ImportError: cannot import name return_selected。可能是因为我在方法中导入视图,在表单中导入方法,在视图中导入表单o.O

我没有其他方法可以制作我需要的东西,但它不能按原样工作。

嗯,我找到了如何传递选择。

forms.py

class MultiTextField(SelectMultipleField):
    widget = widgets.TableWidget()
    option_widget = widgets.TextInput()

class SelectedForm(Form):
    name = MultiTextField()

views.py

@app.route('/home', methods=['GET', 'POST'])
def show_work():
    selected = SelectedForm(request.form)
    choices = []
    for key, value in selected_data.iteritems():
        choices.append((key, value))
    selected.name.choices = choices
    return render_template('home.html', selected=selected)

可以使用selected.name.choices = choices 在视图中添加表单选择。

但是这个表格以奇怪的方式放置数据:

home.html

<form name="selected" action="{{url_for('selected_work', url='result') }}" method="post">
    <p> {{selected.name}}</p>
<input type="submit" value="Calculate">
</form>

在选择中可以说:[(1,"Apple"), (2,"Apple")] 但 html 显示标签“Apple”并在其附近插入数字 1 的文本字段并再次使用数字 2 标记“Apple”插入到文本字段中。

当我提交表单时,它会在文本字段中发送插入的数据,即 ['1', '2']。但不知何故我需要获得:[(Apple,1和插入文本字段中的值),(Apple,2,插入值)]。

【问题讨论】:

    标签: python flask wtforms


    【解决方案1】:

    你有一个循环依赖。查看导入表单,导入方法,导入表单。

    但是您提出的解决方案非常危险。您在模块级别存储数据,这绝对不是线程安全的,并且会导致用户之间的信息泄漏。不要这样做。将数据存储在每个用户的session 中。

    【讨论】:

    • 我考虑过会话,但它不会成功。我在同一页面上有 10 种不同的表格。每个表单都是一个复选框列表。用户可以任意选择。所有选择的值都必须存储在某个地方。为此,我使用 dict 类型的全局变量。不知道如何使用会话。
    • 我不明白表格的数量与它有什么关系。如果您从表单中获取数据,则输入 request.session 而不是全局字典。你不能使用全局字典。
    • 如果我这样做,在函数中使用它时,我得到:RuntimeError('working outside of request context')。
    【解决方案2】:

    感谢 Daniel 对 session 的建议。我现在将所选数据存储在会话中。

    这是我解决任务的方法。我决定不使用 wtforms 表单来呈现通过复选框选择的数据。我保留会话中的所有选择

    views.py

    import methods
    from forms import ...
    
    def make_record(works):
    if session['data']:
        if not works:
            pass
        else:
            for work in works:
                session['data'].append(work)
    else:
        session['data'] = [works]
    
    @app.route('/home', methods=['GET', 'POST'])
    def show_work():
        demount = DemountForm(request.form)
        tile = TileForm(request.form)
        chosen = []
        for each in session['data']:
            chosen.append(each)
        selected = methods.get_selected(chosen)
        return render_template('home.html', demount=demount, tile=tile, selected = selected)
    
    @app.route('/home/<path:url>', methods=['GET', 'POST'])
    def select_work(url):
        db = url
        if db:
            form = DemountForm(request.form)
            work = form.name.data
            make_record(work)
        return redirect(url_for('show_work'))
    

    methods.py

    def get_selected(ids):
        selected = {}
        for each in ids:
            data = db_session.query(Work.name, Work.dimension).filter(Work.id==each).all()
            data = data[0]
            selected[each] = data
        return selected
    

    home.html

    {% if selected %}
        <div id="chosen">
            <form action="/home">
                {% for key, value in selected.iteritems() %}
                        {{value[0]}}<input type="text" id="{{key}}">{{value[1]}}<br>
                {% endfor %}
                <input type="submit" value="Submit">
            </form>
        </div>
    {% endif %}
    

    通过这种方式,我得到了我需要的东西。在一页上,我得到了带有复选框和 div 的菜单,它们在每个选项附近显示选项和文本字段以插入其他数据。

    【讨论】:

      猜你喜欢
      • 2020-01-10
      • 2017-02-15
      • 2016-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-25
      • 1970-01-01
      • 2023-03-28
      相关资源
      最近更新 更多