簡體   English   中英

在Django ORM中過濾關系字段

[英]Filter on relation field in Django ORM

我有一個模型媒體,它與模型UserMedia(用戶評分)有關系。 還有一個名為UserMatchScore(用戶的匹配分數)的模型,與該問題相關。

在一個視圖中,我正在查詢“媒體”表,在該視圖中,有一個選項只能獲取我的比賽已評級但我尚未評級的媒體。 還會根據我和我的比賽的子集(並非所有對媒體進行過評分的用戶)返回平均收視率。 我用注釋來做。

我要做的是過濾媒體表中尚未評級的元素,但我的比賽已評級,這很簡單,但僅完成一半的工作。 返回所有我尚未評級的媒體,但我的比賽已評級,但是關系字段UserMedia仍包含所有評級,該媒體未過濾,因此無法計算我的比賽子集的平均評級。 這是我正在描述的查詢:

queryset = models.Media.objects
queryset = queryset.filter(
               Q(usermedia__user__id__in=my_matches) & ~Q(usermedia__user=user)
            )

達到預期結果的唯一方法是循環查詢集並篩選UserMedia關系的每個元素,但這太慢了,因此必須使用數據庫查詢來完成。

for el in queryset:                    
    el.usermedia_set.filter(~Q(user=user)).filter(user=my_matches)

有誰知道如何使用Django ORM做到這一點?

使用Prefetch您可以使用預先過濾的查詢集獲取關系的相關對象(對於多對多和反向外鍵關系):

queryset = queryset.filter(
               Q(usermedia__user__id__in=my_matches) & ~Q(usermedia__user=user)
            )

prefetch = UserMedia.objects.filter(user_id__in=my_matches).exclude(user=user)
queryset = queryset.prefetch_related(
    Prefetch('usermedia_set', prefetch, to_attr='filtered_usermedia')
)

for el in queryset:
    for usermedia in el.filtered_usermedia:
        # iterate over the filtered usermedia
        # without any additional queries
        calculate_something(usermedia)                    

請注意,與之前針對主查詢集中的每個對象的一個​​附加查詢相比,這將導致一個附加查詢來預取所有相關對象(因此,總共兩個查詢,無論您獲取多少行)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM