在Django中执行PostgreSQL左外部联接和事例

在Django中执行PostgreSQL左外部联接和事例,sql,django,postgresql,Sql,Django,Postgresql,所以我这里有一个相当复杂的sql查询 SELECT links_link.id, links_link.created, links_link.url, links_link.title, links_category.title, SUM(links_vote.karma_delta) AS karma, SUM(CASE WHEN links_vote.user_id = 1 THEN links_vote.karma_delta ELSE 0 END) AS user_vote FROM

所以我这里有一个相当复杂的sql查询

SELECT links_link.id, links_link.created, links_link.url, links_link.title, links_category.title, SUM(links_vote.karma_delta) AS karma, SUM(CASE WHEN links_vote.user_id = 1 THEN links_vote.karma_delta ELSE 0 END) AS user_vote
FROM links_link
LEFT OUTER JOIN auth_user ON (links_link.user_id = auth_user.id)
LEFT OUTER JOIN links_category ON (links_link.category_id = links_category.id) 
LEFT OUTER JOIN links_vote ON (links_vote.link_id = links_link.id)
WHERE (links_link.id = links_vote.link_id)
GROUP BY links_link.id, links_link.created, links_link.url, links_link.title, links_category.title
ORDER BY links_link.created DESC
LIMIT 20
我所有的关系都很好(我认为),当我在navicat for postgresql中运行这个查询时,它可以完美地工作,但是将它转换成Django可以使用的东西是一个相当大的挑战。我使用的是alpha 1.2之前的开发版本verison(来自subversion存储库),因此我从文档中获得了全套工具

以下是我的笑容模型:

class Category (models.Model):
    created = models.DateTimeField(auto_now_add = True)
    modified = models.DateTimeField(auto_now = True)
    title = models.CharField(max_length = 128)

    def __unicode__(self):
        return self.title

class Link (models.Model):
    category = models.ForeignKey(Category)
    user = models.ForeignKey(User)
    created = models.DateTimeField(auto_now_add = True)
    modified = models.DateTimeField(auto_now = True)
    fame = models.PositiveIntegerField(default = 1)
    url = models.URLField(max_length = 2048)
    title = models.CharField(max_length = 256)
    active = models.BooleanField(default = True)

    def __unicode__(self):
        return self.title

class Vote (models.Model):
    link = models.ForeignKey(Link)
    user = models.ForeignKey(User)
    created = models.DateTimeField(auto_now_add = True)
    modified = models.DateTimeField(auto_now = True)
    karma_delta = models.SmallIntegerField(default = 1)

    def __unicode__(self):
        return str(self.karma_delta)
我怎么能转身

def latest(request):
    links = Link.objects.all().order_by('-created')[:20]
    return render_to_response('links/list.html', {'links': links})
进入上述疑问


我只在使用类似的东西方面取得了一些进展,但如何处理我对CASE的使用问题是我无法理解的。任何帮助都将不胜感激。我总是喜欢在框架的内置ORM中工作,但是如果需要原始SQL…

我现在没有时间尝试对该查询进行完整的翻译,但是如果该情况是您的主要障碍,我可以告诉您,它目前不受本机支持,您需要使用调用来与一些原始SQL进行转换。比如:

.extra(select={'user_vote': 'SUM(CASE WHEN links_vote.user_id = 1 THEN links_vote.karma_delta ELSE 0 END')})
但是如果这个查询工作得很好,为什么还要麻烦将它转换成ORM呢?只是Django的ORM故意不是100%的解决方案,这是它公开原始游标API的原因


更新:自Django 1.2以来,还可以让您进行原始SQL查询并取回模型对象(感谢Van Gale)。

我现在没有时间尝试对该查询进行完整翻译,但如果案例是您的主要障碍,我可以告诉您,它目前不受本机支持,为此,您需要使用对的调用和一些原始SQL。比如:

.extra(select={'user_vote': 'SUM(CASE WHEN links_vote.user_id = 1 THEN links_vote.karma_delta ELSE 0 END')})
但是如果这个查询工作得很好,为什么还要麻烦将它转换成ORM呢?只是Django的ORM故意不是100%的解决方案,这是它公开原始游标API的原因

更新:自Django 1.2以来,还有一个功能可以让您进行原始SQL查询并取回模型对象(感谢Van Gale)。

1.2中还有QuerySet.raw():1.2中也有QuerySet.raw():