2011-04-15 82 views
2

我有点困惑于Django的行话。所以我有3个模型:Post,UserProfile(User),Favorite。收藏夹会跟踪用户收藏哪些帖子。Django查询以获取用户最喜爱的帖子?

帖子--->收藏< ---用户/用户配置

最喜爱的模型:

class Favorite(models.Model): 
    user = models.ForeignKey(User, unique=False) 
    post = models.ForeignKey(Post, unique=False) 

    def __unicode__(self): 
     return self.user.username 

用户配置模式:

class UserProfile(models.Model) : 
    user = models.ForeignKey(User, unique=True) 

    def get_favorites(self): 
     if self.user: 
      return self.user.favorite_set.all() 

在我post_list鉴于我通过所有帖子到我的模板,并在模板中我有一个for循环显示所有职位。

{% for post in post_list %} 
<hr/> 
<div id=”post_{{ post.id }}”> 
    {% include 'posts/_post.html' %} 
</div> 
{% endfor %} 

现在,在循环中,我想把一个逻辑,将显示“收藏”!如果登录的用户已经收到邮件。我认为传统的SQL是这样的:

SELECT favorite.post FROM favorite WHERE favorite.user = user.id 

所以,在模板循环我可以做

{% if post in the.above.SQL.query%}Favorited!{% endif %} 

现在我不能把这一对Django的行话出于某种原因。非常感谢您的帮助!

回答

11

需要认识的是,您的Favorite模型实际上是Post和User之间的多对多关系的直通表。如果你在某处声明了一个ManyToManyField,Django实际上可以自动管理它。就个人而言,我会做到这一点对用户配置 - 这样的关系却成为邮政和用户配置之间的一个:

class UserProfile(models.Model): 
    favorites = models.ManyToManyField(Post, related_name='favorited_by') 

现在你不需要你get_favorites方法,因为它通过userprofile.favorites.all()可用。您可以以此为-是模板:

{% if post in userprofile.favorites.all %}Favorited!{% endif %} 

但是这将最终成为极其低效的,因为你会做在您的帖子列表中的每个岗位相同的相同的查询。因此,使用{% with %}标记循环之前获得的最爱一次:

{% with userprofile.favorites.all as favorite_posts %} 
    {% for post in post_list %} 
    {% if post in favorite_posts %}Favorited{% endif %} 
    ... 
    {% endfor %} 
{% endwith %} 
+0

工作就像一个神奇魅力。我从来没有使用ManyToMany,从来没有过多关注它。现在我明白了!谢谢! – rabbid 2011-04-15 10:56:15

3

尽管丹尼尔是一个很好的点,我就只是张贴你想查询:)

Post.objects.filter(favorite__user=user) 
+0

oohhh好的!非常感谢你! – rabbid 2011-04-15 12:40:15