Reputation: 65
I have models like this:
class User(db.Model):
_tablename='user'
id=db.Column(db.Integer, primary_key=True)
name=db.Column(db.String)
email=db.Column(db.String)
class Post(db.Model):
_tablename='post'
id=db.Column(db.Integer, primary_key=True)
title=db.Column(db.String)
user=db.Column(db.Integer, db.ForeignKey('user.id'))
I would like to display the list of all posts on a web page, with something like this in html:
{% for entry in entries %}
<tr>
<td> {{ entry.id }} </td>
<td> {{ entry.title }} </td>
<td> {{ entry.user_name }} </td>
<td> {{ entry.user_email }} </td>
{% endfor %}
However, I don't know how to access the user and email from the user table, using the user.id foreign key. I tried
posts = Post.query.all()
for post in posts:
post.user_name = User.query.filter_by(id=post.id).first()
return render_template('post.html', entries=posts)
But then instead of returning just the name and email, like the title from post, it is returning something like (u'User A',) and (u'[email protected]',).
Upvotes: 5
Views: 12237
Reputation: 113
Other answers ask you to create a second query to get the user name & email, but this is actually not necessary if you add the following to your User class definition:
posts=db.relationship('Post', backref='post_owner',lazy=True)
Your full User class definition will then be:
class User(db.Model):
_tablename='user'
id=db.Column(db.Integer, primary_key=True)
name=db.Column(db.String)
email=db.Column(db.String)
posts=db.relationship('Post', backref='post_owner', lazy=True)
Your html can then take advantage of the relationship by referencing the 'backref' name:
{% for entry in entries %}
<tr>
<td> {{ entry.id }} </td>
<td> {{ entry.title }} </td>
<td> {{ entry.post_owner.name }} </td>
<td> {{ entry.post_owner.email }} </td>
{% endfor %}
This saves you from writing additional queries and cluttering your code with additional 'if' statements.
Upvotes: 2
Reputation: 1
First of all the solution is to query using the related fields. You can get the user details using the below query: Let us assume that the id in the user model is 1 and user in post model value is 1 i.e(id=1, user=1).
Link post model with user model You will have link them with the related fields i.e (User model has id and Post model has user as a foreign key)
import Post #import post model
user = User.query.filter(User.id==Post.user).first()
The below will give first post in post model created by the user
import User #import user model
post = Post.query.filter(Post.user==User.id).first()
post.id
post.title
user.name
user.email
You can also query to get all posts like below
posts = Post.query.filter(Post.user==User.id).all()
Upvotes: 0
Reputation: 33309
You are almolst there but this code below does not actually return the username. It returns the entire user object:
User.query.filter_by(id=post.id).first() # Does Not return user_name but returns the user object
So I would call it something like:
userobj = User.query.filter_by(id=post.id).first()
Then you can retrieve the username,email as:
if userobj is not None: # Make sure user exists
username = userobj.name
email = userobj.email
As a shortcut, you can also do:
username = User.query.filter_by(id=post.id).first().name
email = User.query.filter_by(id=post.id).first().email
Upvotes: 5