Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to redirect from helper function in Flask?

Tags:

python

flask

On many forms we have a cancel button. Trying to keep things DRY it seemed that a helper function was in order. The function if_form_cancel() would check to see if the cancel button had been clicked and then redirect accordingly (with destination passed to the function). However, the redirect is ignored when we use a helper function (it works just fine in-line).

view.py

from helper.py import if_form_cancel
...

def index():
    return render_template('index.html')

def edit():
    ...
    form = EditForm(obj=user, csrf_enabled=False)
    if request.method == 'POST':
        if_form_cancel(url_for('.index')) 
        if form.validate():
            ...
            return redirect(url_for('.index'))
        return render_template('edit.html')

helper.py

from flask import request, redirect, flash

def if_form_cancel(destination='/'):
    try:
        if request.form['cancel']:
            flash(u'Operation canceled at user request')
            return redirect(destination)
    except KeyError:
        pass

edit.html

....
<input type="submit" name="submit" value="Submit" />
<input type="submit" name="cancel" value="Cancel" />
....

Result if cancel button is clicked: helper function is called, correct message is flashed, but redirect does not occur. Is it possible to redirect from a helper function like this? If so how? What are we doing wrong?

like image 822
PartialOrder Avatar asked Nov 15 '13 14:11

PartialOrder


1 Answers

You aren't returning the result of if_form_cancel in the edit function. But you only want to return if the user cancelled. An exception would work well here, and it looks like werkzeug has such an exception.

See if this will work (untested).

from werkzeug.routing import RequestRedirect

def if_form_cancel(destination='/'):
    try:
        if request.form['cancel']:
            flash(u'Operation canceled at user request')
            raise RequestRedirect(destination)
    except KeyError:
        pass

Alternatively, you could just have the form_cancel helper check the form and return True if the user cancelled, and do the redirect in the view itself.

def edit():
    ...
    form = EditForm(obj=user, csrf_enabled=False)
    if request.method == 'POST': 
        if form_cancel():
            return redirect(url_for('.index'))
        if form.validate():
            ...
            return redirect(url_for('.index'))
        return render_template('edit.html')

Also, consider using validate_on_submit instead of checking for POST manually.

https://flask-wtf.readthedocs.org/en/latest/quickstart.html#validating-forms

like image 138
FogleBird Avatar answered Sep 20 '22 08:09

FogleBird