什么是最好的django方式来执行跨越几个表的查询?

时间:2010-03-24 18:34:06

标签: python mysql database django

我有一个评论/评级网络应用程序,一个Digg。我的django应用content有以下型号:

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表达这一点?我已经阅读了文档,但是我无法理解它。

2 个答案:

答案 0 :(得分:10)

我会用:

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

这将按照您的要求获取所有推荐对象,并且select_related会将所有相关的用户和内容对象加载到内存中,以便后续访问它们不会再次访问数据库。

您如何构建此查询实际上与您之后处理返回的数据有很大关系。根据您使用它的方式,单向与另一种方式相比可能或多或少有效。alt text http://sonicloft.net/im/52

答案 1 :(得分: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()来避免重复。