简体   繁体   中英

Passing in Session data from Flask to WTForms

So I'm having issues with passing in a list from my Flask session object into the WTForms that I'm using. I'm trying to access the 'strategy' object (it's a list) within the session object.

The goal is to list all of the strategies that are associated with the current user.

Within the Flask app:

class Create_Indicator_Form(Form):
    security = TextField('Ticker Name', [
                         validators.Required(),
                         validators.Length(min=1, max=6)])
    mva_10 = BooleanField('10 day moving average')
    mva_25 = BooleanField('25 day moving average')
    strategy = SelectField('strategy', session['strategy'])
    def validate_mva_10(form, field):
        if form.mva_25.data is True and field.data is True:
            raise ValidationError('You can only choose one reference')
        if form.mva_25.data is False and field.data is False:
            raise ValidationError('You must choose at least one reference')

@app.route('/create_indicator', methods=['GET', 'POST'])
def create_indicator():
    check_if_logged_in()
    f = request.form
    create_indicator_form = Create_Indicator_Form(f)
    if request.method == 'POST' and create_indicator_form.validate():
        indicator_id = get_next_index('indicator', 'indicator_id')
        ticker = create_indicator_form.security.data
        if create_indicator_form.mva_10.data is True:
            mva_10_day = 'Y'
            mva_25_day = 'N'
        else:
            mva_10_day = 'N'
            mva_25_day = 'Y'
        row = [indicator_id, ticker, mva_10_day, mva_25_day]
        add_data('indicator', row)
        # adding relation
        criteria_row = [session['strategy'][0], indicator_id]
        add_data('criteria', criteria_row)
        return redirect(url_for('home'))
    create_indicator_form.strategies = session['strategy']
    return render_template('create_indicator.html',
                           form=create_indicator_form)

When I try to run the flask app I'm thrown this error:

RuntimeError: working outside of request context

with a trace back to where I access the session object in the Create_Indicator_Form class.

I've realized since starting to try to fix this that it'd be more efficient to chose between the mva_10 and mva_25 with a select field but I would like to resolve this issue before refactoring.

Why

This is because the strategy = SelectField('strategy', session['strategy']) line is executed when the file is loaded, as it is part of the Create_Indicator_Form class definition.

At this time, you're indeed working outside of request context

How to fix it

Using a class factory will work here:

def CreateIndicatorForm():

    class IndicatorForm(Form):
        security = TextField('Ticker Name', [
                             validators.Required(),
                             validators.Length(min=1, max=6)])
        mva_10 = BooleanField('10 day moving average')
        mva_25 = BooleanField('25 day moving average')
        strategy = SelectField('strategy', session['strategy'])
        def validate_mva_10(form, field):
            if form.mva_25.data is True and field.data is True:
                raise ValidationError('You can only choose one reference')
            if form.mva_25.data is False and field.data is False:
                raise ValidationError('You must choose at least one reference')

    return IndicatorForm

Be mindful that calling CreateIndicatorForm() returns a Form class , so to instantiate an actual form, you need to use: CreateIndicatorForm()() (ie "call" the class, like you would any other class to create a new instance).

When instantiating the form, you can (and should) pass arguments to the form constructor, such as the request data: CreateIndicatorForm()(request.form) .


Also, making session['strategy'] an argument of the factory function would be better practice here - this would make the factory reusable outside of request context and would ensure you don't have to create a new form class for every single request.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM