我偶然發現了這個問題,我無法不訴諸原始SQL來解決,但我不想重寫整個查詢。
以下是關於如何使用外部原始sql擴充查詢集而不必關心生成查詢集的實際查詢的說明。
下面是一個典型場景:你有一個像網站reddit的一個LinkPost模型和UserPostVote模式,就像這樣:
class LinkPost(models.Model):
some fields....
class UserPostVote(models.Model):
user = models.ForeignKey(User,related_name="post_votes")
post = models.ForeignKey(LinkPost,related_name="user_votes")
value = models.IntegerField(null=False, default=0)
其中userpostvote表收集的用戶的票上的帖子。 現在,您正在嘗試使用分頁應用顯示用戶的首頁,但您希望箭頭對用戶已投票的帖子顯示爲紅色。
首先你得到的職位頁:
post_list = LinkPost.objects.all()
paginator = Paginator(post_list,25)
posts_page = paginator.page(request.GET.get('page'))
所以現在你通過選擇職位,以顯示Django的分頁程序生成的查詢集posts_page。我們現在如何在將每個帖子呈現在模板中之前添加用戶投票的註釋?
這裏是棘手的,我無法找到一個乾淨的ORM解決方案。 select_related不會允許您僅獲取與登錄用戶相對應的投票,並且循環發佈帖子會執行一堆查詢而不是一個,並且執行所有原始意思是我們不能使用分頁應用程序中的查詢集。
因此,這裏是我如何做到這一點:
q1 = posts_page.object_list.query # The query object of the queryset
q1_alias = q1.get_initial_alias() # This forces the query object to generate it's sql
(q1str, q1param) = q1.sql_with_params() #This gets the sql for the query along with
#parameters, which are none in this example
我們現在擁有的查詢集查詢,只是包裝它,別名和左外連接到它:
q2_augment = "SELECT B.value as uservote, A.*
from ("+q1str+") A LEFT OUTER JOIN reddit_userpostvote B
ON A.id = B.post_id AND B.user_id = %s"
q2param = (request.user.id,)
posts_augmented = LinkPost.objects.raw(q2_augment,q1param+q2param)
瞧!現在我們可以在擴充的查詢集中訪問post.uservote。 而我們只需用一個查詢就可以打開數據庫。
在可能性是兩個查詢:'UserFoo.objects.filter .select_related(用戶= request.user)( 「富」)'然後'Foo.objects.exclude(userfoo__user = request.user)'但尋找其他可能性 –
什麼是最終目標/什麼是用例? –
@Dan我希望這個問題很清楚:UserFoo包含關於Foo的每個用戶的信息,我想顯示一個Foo的註釋列表,其中包含來自UserFoo的用戶信息,用於request.user –