How do I use ndb KeyProperty properly in this situ

2019-02-18 17:51发布

I have two models:

class User(ndb.Model):
    email = ndb.StringProperty(required=True)
    name = ndb.StringProperty(required=True)

class Post(ndb.Model):
    created = ndb.DateTimeProperty(auto_now_add=True)
    message = ndb.TextProperty(required=True)
    user = ndb.KeyProperty(kind=User)

If I want to loop through some posts in the Post model. How I would access the 'name' field in the User model? For example:

for post in posts:
    print post.message
    print post.user.name

So I'm guessing the last line isn't correct. I tried searching and couldn't figure it out. And to add to that. Is there a way to access that info in a Jinja2 template?

And then finally, am I going about this wrong? Let's say there are 50 posts. And I have 1 query to get those 50 posts. Is accessing the 'name' field on the User model going to be an additional query for each time it loops? So 51 queries?? If so, is it better to not use KeyProperty and just store the User data with each post (even if I have more data like avatar, user_id, etc)?

1条回答
来,给爷笑一个
2楼-- · 2019-02-18 18:36

If I recall correctly, a KeyProperty will return you a ndb.Key. Once you have the key, it is easy to get the model instance (key.get()). So, in your example, you would:

print post.user.get().name

As far as accessing it in a jinja template -- Sure, it'd just be something like:

{% for post in posts %} 
{{ post.message }}
{{ post.user.get().name }}
{% endfor %}

And yes, this will interact with the datastore once for each key you have. If you'd rather, you can factor it out into one datastore interaction:

keys = [p.user for p in posts]
users = ndb.get_multi(keys)
user_posts = zip(users, posts)

And then in your jinja template:

{% for user, post in user_posts %}
{{ post.message }}
{{ user.name }}
{% endfor %}
查看更多
登录 后发表回答