簡體   English   中英

Django:將兩個查詢合二為一

[英]Django: Combining two queries into one

我目前很難將query_1query_2組合成一個query_combined 你知道如何實現這一目標嗎?

query_1 = (
    Response.objects.filter(
        survey__event=12,
        survey__template=settings.SURVEY_POST_EVENT,
        answers__question__focus=QuestionFocus.FEELING_ABOUT_ATTENDING_AGAIN,
    ).filter(answers__answer="Very disappointed")
)

query_2 = (
    Response.objects.filter(
        survey__event=12,
        survey__template=settings.SURVEY_POST_EVENT,
        answers__question__focus=QuestionFocus.RECOMMENDATION_TO_FRIENDS,
    )
    .annotate(answer_num=Cast("answers__answer", IntegerField()))
    .filter(answer_num__gt=8)
)

這是解決方案:

combined_query = (
    Response.objects.filter(
        survey__event=12,
        survey__template=settings.SURVEY_POST_EVENT,
        answers__question__focus__in=[
           QuestionFocus.FEELING_ABOUT_ATTENDING_AGAIN,
           QuestionFocus.RECOMMENDATION_TO_FRIENDS,
        ],
    )
    .annotate(
        answer_NPS=Case(
            When(
                answers__question__type=QuestionType.NPS,
                then=Cast(
                    'answers__answer', output_field=IntegerField()
                )
            )
        )
    )
    .filter(
        answers__choices__answer="Very disappointed",
        answer_NPS__gte=9
    ).order_by("-created")
)

嘗試這個:

 from django.db.models import Q

 Response.objects.filter(
        survey__event=12,
        survey__template=settings.SURVEY_POST_EVENT,
        answers__answer="Very disappointed",
     answer_num__gt=8,Q(answers__question__focus=QuestionFocus.FEELING_ABOUT_ATTENDING_AGAIN) 
   | Q(answers__question__focus=QuestionFocus.RECOMMENDATION_TO_FRIENDS)
    ).annotate(answer_num=Cast("answers__answer", IntegerField()))

可能使用django.db.models.Q會有所幫助。 以下行中的某些內容(尚未對其進行測試,因此可能需要進行一些調整):

combined_query = (
    Response.objects.filter(
        survey__event=12,
        survey__template=settings.SURVEY_POST_EVENT,
        answers__question__focus__in=[
           QuestionFocus.FEELING_ABOUT_ATTENDING_AGAIN,
           QuestionFocus.RECOMMENDATION_TO_FRIENDS,
        ],
    )
    .annotate(answer_num=Cast("answers__answer", IntegerField()))
    .filter(Q(answers__answer="Very disappointed") | Q(answer_num__gt=8))
)

您可以使用| Q object 的運算符來組合兩個查詢:

from django.db.models import Q

query_combined = (
    Response.objects.filter(
        survey__event=12,
        survey__template=settings.SURVEY_POST_EVENT
    )
    .annotate(answer_num=Cast("answers__answer", IntegerField()))
    .filter(
        Q(
            answers__question__focus=QuestionFocus.FEELING_ABOUT_ATTENDING_AGAIN,
            answers__answer="Very disappointed"
        ) |
        Q(
            answers__question__focus=QuestionFocus.RECOMMENDATION_TO_FRIENDS,
            answer_num__gt=8
        )
    )
)

應該可以使用Q 表達式 保存一個查詢是否值得讓代碼更復雜? 無論如何,這是一個鏡頭,未經測試......

Response.objects.filter(
    survey__event=12,
    survey__template=settings.SURVEY_POST_EVENT
).annotate(answer_num=Cast("answers__answer", IntegerField())
).filter(
     ( Q(answers__question__focus=QuestionFocus.FEELING_ABOUT_ATTENDING_AGAIN) & 
       Q(answers__answer="Very disappointed") ) 
     |
       Q(answers__question__focus=QuestionFocus.RECOMMENDATION_TO_FRIENDS) &
       Q(answer_num__gt=8)
)

這並不完全相同,因為前半部分檢索到的所有對象現在也將被注釋。

您可以使用 itertools 的鏈 function。

from itertools import chain

combined = chain(query1, query2)

暫無
暫無

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

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