Question

I am creating an application using Flask, SQLAlchemy, and Jinja. Almost every page in my application uses a base.html file (which is essentially a shell with a navbar and sidebar), and then builds upon that. I display information in the base.html file that is the result of a SQLAlchemy query:

user.company.users.filter(User.account_approved == False).all()

and right now I am passing it to a single view by using:

@splash.route('/dashboard')
@login_required
def dashboard():
    return render_template('templates/dashboard.html', pendingUsers=g.user.company.users.filter(User.account_approved == False).all())

However, this only allows the base.html view to have this information when I load the /dashboard route, and if I load any other route that uses the same base.html file, running {{ pendingUsers}} outputs not text. How can I go about rendering that query in every route that uses base.html? I tried making the query directly in the jinja template, but I could not figure out how to do that (for example, running {{ g.user.company.users }} simply outputted the SQL query for that SQLAlchemy statement.

Was it helpful?

Solution

What you are doing is not going to work because your query is not evaluated when you call it within render_template. Instead, the sql query string is sent as is to the template.

You can use a custom decorator since only want to do this for some views/pages.

def get_pending_users(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        pending_users = user.company.users.filter(User.account_approved == False).all()
        if g.pending_users is None:
           g.pending_users = pending_users
        return f(*args, **kwargs)
    return decorated_function

In your view, you can call it as:

@app.route('/',methods = ['GET','POST])
@get_pending_users
def whatever():
    return render_template('templates/dashboard.html')

Then, in your template, just call g.pending_users

 {{ g.pending_users }}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top