2010-03-24 83 views
2

我有一个评论/评级的网络应用程序,la Digg。我的Django应用程序content有以下型号:什么是跨越多个表的查询最好的Django方式?

class Content(models.Model): 
    title = models.CharField(max_length=128) 
    url = models.URLField(max_length=2048) 
    description = models.TextField(blank=True) 

class Recommendation(models.Model): 
    user = models.ForeignKey(User) 
    content = models.ForeignKey(Content) 
    review = models.TextField() 
    rating = models.PositiveSmallIntegerField() 
    class Meta: 
     unique_together = ('user', 'content') 

class Subscription(models.Model): 
    subscriber = models.ForeignKey(User, related_name='subscription_set') 
    publisher = models.ForeignKey(User, related_name='publication_set') 
    class Meta: 
     unique_together = ('subscriber', 'publisher') 

我想建立一个页面,所有用户的所有建议为之当前用户(request.user)签约。

如果我写这篇文章的SQL,我相信我会用类似下面的查询结束:

select content_content.*, content_recommendation.*, auth_user.* 
from content_content, content_recommendation, content_subscription, auth_user 
where content_content.id = content_recommendation.content_id 
and content_recommendation.user_id = content_subscription.publisher_id 
and content_subscription.subscriber_id = ? 
and auth_user.id = content_subscription.publisher_id; 

我将如何表达这种使用Django的查询API的?我已经阅读过文档,但是我无法理解它。

回答

10

我会用:

Recommendation.objects.filter(user__publication_set__subscriber=request.user).select_related() 

这将让你,你要求所有的推荐对象,并select_related将所有相关的用户和内容对象加载到内存中,这样以后他们的访问不会再次击中DB。

你如何构造这个查询的确与处理返回的数据有很大关系。根据你对它的做法,以一种方式与另一种方式进行比较可能会更有效率。 alt text http://sonicloft.net/im/52

1

我认为这是:

Content.objects.filter(recommendation_set__user__publication_set__subscriber__pk=request.user.pk)/.distinct()/ 

Recommendation.objects.filter(user__publication_set__subscriber__pk=request.user.pk)/.distinct()/ 

- 哪种模式取决于情况下,你想要得到的。可能需要Distinct()来避免重复。

相关问题