How to get Flask-SQLAlchemy object to load child relations elements for Jinja template?

I have basic models for User and Post. In my User model, I have

posts = db.relationship('Post', backref='user', lazy='dynamic') 

However, when I do something like

 return render_template('user.html', users=users) 

I want to do something like

 {% for user in users %} <tr> <td>{{ user.id }}</td> <td>{{ user.posts|length }}</td> </tr> {% endfor %} 

Unfortunately this does not work. Messages are a request, not a b / c lazy='dynamic' object. I can do the above if I change lazy='joined' , but then it will download all messages for users at any time when I request a user.

I tried adding .options(joinedload('posts')) to my request, but he said that

InvalidRequestError: "User.posts" does not support a population of objects. You cannot use a downloadable download.

Any help is appreciated.

+7
python flask jinja2 flask-sqlalchemy sqlalchemy
source share
3 answers

Just remove the lazy="dynamic" argument and you can use joinedload without any problems. (Remember that when you do this, you open yourself up to a complex diagnosis of problems with the N + 1 query. If you always need messages, use joined instead).

If you need all the behavioral requirements (queriable, joinable and lazy-load), I suggest looking at this question , which suggests adding another attribute for dynamic queries:

 class User(db.Model): posts = db.relationship('Post', backref='user') class Post(db.Model): # etc. User.posts_query = db.relationship(Post, lazy='dynamic') 
+7
source share

This is an object, but these request objects have methods that can help you. In particular, for this use case you can:

 {% for user in users %} <tr> <td>{{ user.id }}</td> <td>{{ user.posts.count() }}</td> </tr> {% endfor %} 
0
source share

You must execute .first () or .all () on your request object in order to get the actual object / list.
e.g. users = User.query.all()

-one
source share

All Articles