在这种情况下,我该如何正确使用ndb KeyProperty?

3

我有两个模型:

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)

如果我想在Post模型中循环一些帖子,我该如何访问User模型中的“name”字段?例如:
for post in posts:
    print post.message
    print post.user.name

所以我猜最后一行不正确。我尝试搜索但是无法弄清楚。还有,是否有一种方法可以在Jinja2模板中访问该信息?

最后,我的做法是否错误?假设有50篇文章。我只需要1个查询来获取这50篇文章。每次循环时访问用户模型上的“name”字段会产生额外的查询吗?因此有51个查询?如果是这样,是否最好不使用KeyProperty并仅将用户数据与每篇文章一起存储(即使我有更多数据如头像、用户ID等)?


1
我建议将User作为Post的父类:减少写入、索引和成本。文档 - Gianni Di Noia
1
好的,很酷。我也会检查这个。我可能需要在SO上开始一个新的问题,以弄清如何使用它 :) - TylerW
1个回答

6

如果我没记错的话,KeyProperty 会返回一个 ndb.Key。一旦你拥有了这个键,就可以很容易地获取模型实例 (key.get())。所以,在您的示例中,您将执行以下操作:

print post.user.get().name

如果在Jinja模板中访问它--当然,只需要像这样:

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

是的,这将针对您拥有的每个键与数据存储进行交互。如果您愿意,您可以将其因素分解为一个数据存储交互:

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

然后在您的Jinja模板中:

{% for user, post in user_posts %}
{{ post.message }}
{{ user.name }}
{% endfor %}

糟糕!我尝试过了,但是没有成功。但是我发现有些帖子中缺少用户键导致出错。我已经修复了这个问题,现在它可以正常工作了!我会测试第二部分以减少查询次数。谢谢! - TylerW
啊,是的。我猜那会给没有用户的帖子一个AttributeError。毕竟,None.get() 没有什么意义 :). - mgilson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接