【问题标题】:Flask SQL Alchemy - How do I update several records at once through a formFlask SQLAlchemy - 如何通过表单一次更新多条记录
【发布时间】:2021-02-13 18:36:31
【问题描述】:

我从根本上为如何在 SQL Alchemy 中使用表单而苦苦挣扎。我所做的每个教程和示例都侧重于单个记录表单,其中每个字段都可更新以最终生成记录。

我想将我的数据显示为一个充满(c100 行)事务的表,仅更新一列的每一行。这是一份支出清单,我想确定哪些交易要从分析中排除。我可以将其呈现为每行一个表单字段的表格,但是当我将其提交回我的视图时,我无法获取表格行 ID 以将其写入数据库。

有没有人知道一个示例或教程,其中重点是管理许多记录?也许是用于管理数据库中所有条目的管理功能或其他什么?例如选择所有这些记录然后删除它们。

我的代码如下,但老实说,我想知道我是否以正确的方式进行。

我的模特:

class Transaction(db.Model):
__tablename__ = 'transactions'
id = db.Column(db.Integer, primary_key=True)
date = db.Column(db.Date, index=True)
description = db.Column(db.String(128), index=True)
amount = db.Column(db.Float, index=True)
balance = db.Column(db.Float)
excluded = db.Column(db.Integer, index=True)
source_id = db.Column(db.Integer, db.ForeignKey('sources.id'))
category_id = db.Column(db.Integer, db.ForeignKey('categories.id'))

我的表格:

class TransExclude(FlaskForm):
excluded = SelectField('Exclude', choices = EXCLUDED_CHOICES, validators=[DataRequired()])
submit = SubmitField('Add')

我的观点:

@app.route('/exclude_transactions', methods=['GET', 'POST'])
    def exclude_transactions():
        form = TransExclude()
        if request.method == "POST":
           # This is where I need the ID of the record as well as the excluded return...
           # excluded = dict(EXCLUDED_CHOICES).get(form.excluded.data)
           req = request.form
           df = pd.DataFrame(list(req.items(1)))
           print(df)

           flash('Congratulations, you have updated the exclusions!')
           return redirect(url_for('process_new_month'))

    transactions = Transaction.query.all()
    return render_template('excludes.html', title= 'Monthly Excludes',transactions=transactions, form=form)

还有我的 HTML:

{% extends "base.html" %}
{% import 'bootstrap/wtf.html' as wtf %}

{% block app_content %}

<div class="container">
    <div class="row">
        <div class="col-sm">
            <br>
            <h2>Exclude Transactions</h2>
            <hr>
            <form method="post">
            <table class="table table-striped">
                 <thead>
                    <tr>
                        <th>ID</th>
                        <th> Date</th>
                        <th>Description</th>
                        <th> Amount</th>
                        <th>Exclude?</th>
                        <th></th>

                    </tr>
                 </thead>

                 <tbody>
                 {% for transaction in transactions %}
                    <tr>
                       <td>{{transaction.id}}</td>
                       <td>{{transaction.date}}</td>
                       <td>{{transaction.description}}</td>
                       <td>{{transaction.amount}}</td>
                        <td>{{form.excluded}}</td>
                    </tr>

                 {% endfor %}
                 </tbody>
            </table>
            <button type="submit" class="btn btn-primary">Exclude Items</button>
            </form>
        </div>
    </div>
</div>

{% endblock %}

【问题讨论】:

    标签: python flask flask-sqlalchemy flask-wtforms


    【解决方案1】:

    以下代码向您展示了一个将 FieldList 类型的字段与 FormFields 结合使用的示例。在每个嵌套表单内都有一个隐藏字段,其中包含数据记录的 ID。为此,在创建父表单时,会在字典中填充所需的数据。
    为了便于理解,我在代码中写了cmets。

    这个解决方案肯定不是最优的,但它是可能的。
    我认为您应该能够将此变体应用到您的代码中。

    class Item(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        title = db.Column(db.String, nullable=False)
    
    class _SubForm(Form):
        # The HiddenField later contains the id of the data record. 
        id = HiddenField('id')
        excluded = SelectField('Exclude', choices=EXCLUDED_CHOICES, validators=[DataRequired()])
    
        # The constructor is overwritten in order to bypass further fields for the csrf token. 
        def __init__(self, csrf_enabled=False, *args, **kwargs):
            super(_SubForm, self).__init__(csrf_enabled=csrf_enabled, *args, **kwargs)
    
    class EditForm(FlaskForm):
        items = FieldList(FormField(_SubForm))
    
    @app.route('/edit', methods=['GET', 'POST'])
    def edit():
        # Fill in the form with the necessary data. 
        items = Item.query.all()
        form = EditForm(request.form, data={ 'items': items })
        if form.validate_on_submit():
            # Iterate over the FieldList here. 
            for field in form.items.data:
                id = item_field.get('id')
                excluded = item_field.get('excluded')
                print(id, excluded)
        return render_template('edit.html', **locals())
    
    <form method="post">
      {{ form.csrf_token }}
      <table>
        {% for field in form.items -%}
        <tr>
          <td>
            {{ items[loop.index0].title }}
          </td>
          <td>
            {{ field.hidden_tag() }}
            {{ field.excluded }}
          </td>
        </tr>
        {% endfor -%}
      </table>
      <input type="submit" />
    </form>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-06
      • 2019-09-17
      • 1970-01-01
      • 2016-08-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多