pythonflask

How to set default value in QuerySelectField


I need help with my Flask app. I have page with FlaskForm and use QuerySelectField so that user can select warehouse form database. I use SQLAlchemy with SQlite database.

Here is my code for database model:

class ozonWarehouse(db.Model):
    __tablename__ = "ozonWarehouses"

    id = db.Column(db.Integer, primary_key=True)
    type = db.Column(db.String(32))
    name = db.Column(db.String(64), index=True, unique=True)
    enabled = db.Column(db.Boolean)

    def __repr__(self):
        return '<Ozon Warehouse {}>'.format(self.name)

Here is my code for building a form:

class ozonUnitEcForm(FlaskForm):
    ...
    fboWarehouseFrom = QuerySelectField('Склад отправки партии товара', 
                query_factory=lambda: db.session.execute(
                db.select(ozonWarehouse)).scalars(), 
                get_label='name')
    ...
    submit = SubmitField('Рассчитать')

When loading a page with this form I need a default value to be selected in QuerySelectField. ID of the warehouse which must be selected comes in dictionary 'productData' with key 'fboWarehouseFrom'. So that if productData['fboWarehouseFrom'] = 3 the warehouse with ID = 3 must be selected in QuerySelectField.

Here is the screenshot of database table for greater clarity: database table screenshot

And here is my code for URL processing of this page:

@app.route('/ozon-unit-economy', methods=['GET', 'POST'])
def ozonUnitEconomy():
    ozonProductId = request.args.get('id')
    productData = dict()

    form = ozonUnitEcForm()
    if form.validate_on_submit():
        productData = func.loadOzonProdUEData(form, None, ozonProductId)
        calcResults, miscData, currentDate = func.calcOzonUnitEconomy(productData, form.date.data)
    else:
        productData = func.loadOzonProdUEData(None, None, ozonProductId)
        calcResults, miscData, currentDate = func.calcOzonUnitEconomy(productData, date.today())
        
    ...

    form.fboWarehouseFrom.default = productData['fboWarehouseFrom'] 
    
    ...

    return render_template('ozon-unit-economy.html', title='Юнит-экономика товара Ozon', form=form, productData = productData, miscData = miscData, calcResults = calcResults)

In this code the correct value of warehouse ID is assigned to productData['fboWarehouseFrom'] and then I use it to set the value of form.fboWarehouseFrom.default. I presume that setting value of form.fboWarehouseFrom.default will select the warehouse with this ID in QuerySelectField, but it does not work and QuerySelectField has no selection.

Please advice what is wrong and how to correct it. Thank you!


Solution

  • Update the fboWarehouseFrom.data property in your ozonUnitEconomy route after creating the form:

    @app.route('/ozon-unit-economy', methods=['GET', 'POST'])
    def ozonUnitEconomy():
        ozonProductId = request.args.get('id')
        productData = dict()
    
        form = ozonUnitEcForm()
    
        if form.validate_on_submit():
            productData = func.loadOzonProdUEData(form, None, ozonProductId)
            calcResults, miscData, currentDate = func.calcOzonUnitEconomy(productData, form.date.data)
        else:
            productData = func.loadOzonProdUEData(None, None, ozonProductId)
            calcResults, miscData, currentDate = func.calcOzonUnitEconomy(productData, date.today())
    
        # Set the selected warehouse ID for the QuerySelectField
        selected_warehouse_id = productData.get('fboWarehouseFrom')
        if selected_warehouse_id:
            form.fboWarehouseFrom.data = db.session.execute(
                db.select(ozonWarehouse).filter_by(id=selected_warehouse_id)
            ).scalars().first()
    
        return render_template(
            'ozon-unit-economy.html',
            title='Юнит-экономика товара Ozon',
            form=form,
            productData=productData,
            miscData=miscData,
            calcResults=calcResults
        )