【问题标题】:What's the best django way to do a query that spans several tables?进行跨多个表的查询的最佳 django 方法是什么?
【发布时间】:2011-01-31 09:53:16
【问题描述】:

我有一个评论/评级网络应用程序,一个 la 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 来表达这一点?我已阅读文档,但无法理解。

【问题讨论】:

    标签: python mysql database django


    【解决方案1】:

    我会使用:

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

    这将根据您的请求为您提供所有 Recommendation 对象,并且 select_related 会将所有相关的 User 和 Content 对象加载到内存中,以便后续访问它们不会再次访问数据库。

    不过,您如何构建此查询确实与您之后处理返回的数据有很大关系。根据您对它的处理方式,采用一种方式与另一种方式可能或多或少更有效率。alt text http://sonicloft.net/im/52

    【讨论】:

      【解决方案2】:

      我认为是:

        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() 以避免重复。

      【讨论】:

        猜你喜欢
        • 2015-09-04
        • 1970-01-01
        • 1970-01-01
        • 2017-11-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-05
        • 1970-01-01
        • 2012-07-20
        相关资源
        最近更新 更多