2

I have a problem with my form, so basically I have a SelectField dynamically loaded from database query, and everytime I did an operation to the database, it seems like the SelectField is not updated and following the realtime value in the database.

so here is my code view.py

@app.route('/add/sale-transaction', methods=['GET', 'POST'])
def add_sale_transaction():
    form = forms.ItemSaleForm()

    if form.validate_on_submit():

        # get unsold items to be added so I can mark it sold
        items = models.Item.query.join(models.PurchaseTransaction) \
            .filter((models.Item.sale_transaction_id == None) & (models.Item.item_type_id == form.item_stock.data)) \
            .order_by(models.PurchaseTransaction.transaction_date) \
            .order_by(models.Item.id) \
            .limit(form.quantity.data)

        # for each item add sale transaction field to mark it sold
        for it in items:
            it.sale_price = form.sale_price.data
            it.sale_transaction_id = # something here..
            db.session.add(it)
            db.session.flush()

        db.session.commit()
        flash('Successfuly added new Sale Transaction')
        return redirect(request.path)

    return render_template('add-sale-transaction.html', form=form)

then in my form.py

class ItemSaleForm(wtforms.Form):
    sale_price = IntegerField(label='Sale Price: ',
                              validators=[InputRequired()])

    # get unsold items and its quantity
    unsold_items = db.session.query(models.Item.item_type_id, models.ItemType.item_type, func.count(models.Item.id)) \
        .join(models.ItemType) \
        .filter(models.Item.sale_transaction_id == None) \
        .group_by(models.Item.item_type_id)

    # convert to dict to be used by SelectField
    qty_separator = ' - qty: '
    unsold_items_dict = {}
    for item in unsold_items:
        unsold_items_dict[item[0]] = '{}{}{}'.format(item[1], qty_separator, item[2])

    item_stock = SelectField(label='Item Type: ',
                             coerce=int,
                             choices=unsold_items_dict.items(),
                             validators=[InputRequired()])
    quantity = IntegerField(label='Item Quantity',
                            validators=[InputRequired()])

Here is the explanation, if I access /add/sale-transaction and fill in the form, in the field item_stock (SelectField) it should give me the list of unsold items - item which has no sale_transaction_id and no sale_price - and show its own quantity.

So after I submit the form, obviously some changes happen to list of unsold items, but apparently the SelectField choices= does not change, it still has same value as before.

If I do a manual query after submitting the form, I can see changes in unsold items, so I'm suspecting either the db.session expiry/refresh or form is not recreated during request to '/add/sale-transaction' or maybe the wtform cache something..

Any help?

andiwin
  • 1,552
  • 3
  • 14
  • 27

1 Answers1

0

I've fixed my problems, turns out it is the wtforms that behaves a bit weird with choices attribute for the SelectField. I found some solutions like this, and it solves my problem if I declare choice either in the __init__() or view

Community
  • 1
  • 1
andiwin
  • 1,552
  • 3
  • 14
  • 27