QuerySet: 使用AND的LEFT JOIN

7 投票
2 回答
2262 浏览
提问于 2025-04-16 16:34
LEFT OUTER JOIN "core_rating" ON 
("core_film"."parent_id" = "core_rating"."parent_id" 
AND "core_rating"."user_id" = %i

我在用一个老版本的Django,1.1,里面有个黑科技可以在extra()里支持连接查询。这个方法能用,但现在是时候换新了。Django 1.2开始用RawQuerySet,所以我把代码改成了这个新方法。问题是,RawQuery不支持过滤器,而我的代码里有很多过滤器。

我在网上查资料,发现CaktusGroup上提到可以用query.join()。这听起来不错,但在我的代码里,我已经写了query.join()的第一部分:"core_film"."parent_id" = "core_rating"."parent_id",但我不知道怎么在AND后面加第二部分。

有没有什么办法可以在Django里使用自定义的JOIN,而不需要重写所有的过滤器代码(Raw)呢?

这是我们在extra()里的当前代码片段:

top_films = top_films.extra(  
    select=dict(guess_rating='core_rating.guess_rating_alg1'),  
    join=['LEFT OUTER JOIN "core_rating" ON ("core_film"."parent_id" = "core_rating"."parent_id" and "core_rating"."user_id" = %i)' % user_id] + extra_join,  
    where=['core_film.parent_id in (select parent_id from core_film EXCEPT select film_id from filmbasket_basketitem where "wishlist" IS NOT NULL and user_id=%i)' % user_id,   
           '( ("core_rating"."type"=1 AND "core_rating"."rating" IS NULL) OR "core_rating"."user_id" IS NULL)',  
           ' "core_rating"."last_displayed" IS NULL'],  
     )

2 个回答

2

很遗憾,这里答案是否定的。

Django的ORM(对象关系映射)和Django的大部分内容一样,遵循一种理念:简单的事情应该简单,而困难的事情应该是可以做到的。在这种情况下,你确实遇到了“困难的事情”,而“可能的”解决办法就是直接写原始查询。确实有些情况下,写原始查询会比较麻烦,甚至让人感觉不太舒服,但从项目的角度来看,这种情况发生的频率太低,不值得花费时间去增加这样的功能。

撰写回答