簡體   English   中英

Django結合3個查詢集

[英]Django combine 3 queryset

朋友們好,我不太熟悉將查詢集合並為一個。 如何在不改變模板設計的情況下達到我想要的結果?

注意:我已經問過這個問題了 我剛剛發現在 Django 中有組合多個查詢集這樣的事情。 不過,這不是同一個問題。

這是我的views.py:

Markingbehaviors = StudentsBehaviorGrades.objects.filter(Teacher=teacher) \
        .filter(Students_Enrollment_Records__in=Students.values_list('id')).values('Grading_Period').distinct('Grading_Period')\
        .order_by('Grading_Period')

Marking = StudentsBehaviorGrades.objects.filter(Teacher=teacher) \
        .filter(Students_Enrollment_Records__in=Students.values_list('id'))

cores = StudentsBehaviorGrades.objects.filter(Teacher=teacher) \
        .filter(Students_Enrollment_Records__in=Students.values_list('id')).values(
        'Marking__Marking',
        'Grading_Behavior__Grading_Behavior__Name',
        'Grading_Behavior__Grading_Behavior__GroupName').distinct(
        'Grading_Behavior__Grading_Behavior__Name') \
        .order_by('Grading_Behavior__Grading_Behavior__Name')

behaviors = StudentsBehaviorGrades.objects.filter(Teacher=teacher) \
        .filter(Students_Enrollment_Records__in=Students.values_list('id')).values(
        'Marking__Marking',
        'Grading_Behavior__Grading_Behavior__Name',
        'Grading_Behavior__Grading_Behavior__GroupName').distinct(
        'Grading_Behavior__Grading_Behavior__GroupName') \
        .order_by('Grading_Behavior__Grading_Behavior__GroupName')

matches = cores.union(Marking,behaviors)

這是我的 html:

<tr>
    {% for quarter in Markingbehaviors %}
        td class="tdquarter">Q {{quarter.Grading_Period}}</td>
    {% endfor %}
</tr>


{% for match in matches %}
    <tr>
       <td rowspan="2" colspan="4" class="tblcoretitle">{{match.Grading_Behavior__Grading_Behavior__Name}}</td>
    </tr>
    <tr>
       <td colspan="4" class="tblcore">{{match.Grading_Behavior__Grading_Behavior__GroupName}}</td>
       <td class="tblcore">{{match.Marking.Marking}}</td>
    </tr>
{% endfor %}

這是我的StudentsBehaviorGrades管理站點視圖:

在此處輸入圖片說明

這是我目前的結果:

在此處輸入圖片說明

我想要結果:

在此處輸入圖片說明

更新

當我在我的 views.py 中嘗試這個時:

matches = set(itertools.chain(cores, behaviors,Marking))

我收到此錯誤:

在此處輸入圖片說明

伙計,如果您有更好的解決方案或想法,請分享您的答案。

這就是我渲染的方式

    Marking = StudentsBehaviorGrades.objects.filter(Teacher=teacher) \
        .filter(Students_Enrollment_Records__in=Students.values_list('id'))\
        .order_by('Grading_Behavior__Grading_Behavior__Name')

    cores = StudentsBehaviorGrades.objects.filter(Teacher=teacher) \
        .filter(Students_Enrollment_Records__in=Students.values_list('id')).values(
        'id',
        'Marking__Marking',
        'Grading_Period',
        'Grading_Behavior__Grading_Behavior__Name',
        'Grading_Behavior__Grading_Behavior__GroupName').distinct(
        'id',
        'Grading_Behavior__Grading_Behavior__Name').order_by(
        'id',
        'Grading_Behavior__Grading_Behavior__Name'
        )

    behaviors = StudentsBehaviorGrades.objects.filter(Teacher=teacher) \
        .filter(Students_Enrollment_Records__in=Students.values_list('id')).values(
        'id',
        'Marking__Marking',
        'Grading_Period',
        'Grading_Behavior__Grading_Behavior__Name',
        'Grading_Behavior__Grading_Behavior__GroupName').distinct(
        'id',
        'Grading_Behavior__Grading_Behavior__GroupName').order_by(
        'id',
        'Grading_Behavior__Grading_Behavior__GroupName'
    )

matches = cores.union(Marking,behaviors)

return render(request, 'Homepage/mystudentperreport.html',{ "matches":matches,})

組合查詢集非常簡單。 在組合SOMTIMES時,如果它們相同,您有兩個選擇。

模型深深的只是原始的SQL語句,在組合與SQL發生OR,在蟒蛇而存在。 Q對象用於更復雜的查找。 讓我們來看看。

如果您有 2 個或更多查詢集。

您可以ORAND它們, qs_3 = qs_1 & qs_2它們qs_3 = qs_1 & qs_2同一類型qs_3 = qs_1 & qs_2將返回它們連接在一起

|相同 , 但是,您有不同的類型,這就是Q對象存在的原因。

例如

from django.db.models import Q
my_concatenated_qs = Q(MyModel__my_attr_if_I_want="") & Q(MyAnotherModel)  

| 也有效。

注意: MyModel、MyAnotherModel 不是模型實例,它只是名稱,也不是字符串。 只是沒有引號的原始名稱。

您還可以刪除my_attr_if_I_want ,我只是想表明可以在這里使用__語法。

Q對象不僅限於我展示的模型查詢

例如

complex_queryset = MyModel.objects.filter(
    Q(my_attr__startswith='R') & ~Q(my_another_attr__startswith='Z')
    | Q(my_third_attr__startswith='R') & Q(my_fourth_attr__startswith='R')
)

您還可以否定查詢集

例如

X = True
Y = not X

這是Negation ,否定 Q 對象(不是查詢)

~Q(MyModel__startswith="A") | Q(MyModel__whatever__whatever=[])

此外,您可以在此處閱讀有關 Q 對象的信息

您希望將匹配對象指向具有如下形狀的匹配列表:

matches = [{
        "core_value_name": "core_value_1",
        "behaviour_statements": [{
                "name": "behaviour_statement_1",
                "grades": {
                    "q1": "grade_q1",
                    "q2": "grade_q2",
                    "q3": "grade_q3",
                    "q4": "grade_q4"
                }
            },
            {
                "name": "behaviour_statement_2",
                "grades": {
                    "q1": "grade_q1",
                    "q2": "grade_q2",
                    "q3": "grade_q3",
                    "q4": "grade_q4"
                }
            },
            ...
        ]
    }, {
        "core_value_name": "core_value_2",
        "behaviour_statements": [{
                "name": "behaviour_statement_1",
                "grades": {
                    "q1": "grade_q1",
                    "q2": "grade_q2",
                    "q3": "grade_q3",
                    "q4": "grade_q4"
                }
            },
            ...
        ]
    }
    ...
]

然后你可以使用你的模板做一個小的調整,如下所示:

{% for match in matches %} 
{% set first_row=True %} 
{% for behaviour_statement in match.behaviour_statements %} 
{% if first_row %}
<tr>
  <td rowspan="{% len(match.behaviour_statements) %}" colspan="4" class="tblcoretitle">{{match.core_value_name}}</td>
{% set first_row=False %} 
{% elif %}
<tr>
{% endif %}
  <td colspan="4" class="tblcore">{{behaviour_statement.name}}</td>
  <td class="tblcore">{{behaviour_statement.grades.q1}}</td>
  <td class="tblcore">{{behaviour_statement.grades.q2}}</td>
  <td class="tblcore">{{behaviour_statement.grades.q3}}</td>
  <td class="tblcore">{{behaviour_statement.grades.q4}}</td>
</tr>
{% endfor %} 
{% endfor %}

這會讓你得到你想要的結果。

您的問題有一個非常簡單的解決方案,它不在查詢集區域(有點)。

根據您告訴我們的內容,您正在嘗試按以下順序對每個結果進行分組:

  1. Grading_Behavior__Grading_Behavior__GroupName(組)
  2. Grading_Behavior__Grading_Behavior__Name(姓名)
  3. Grading_Period(季度)

我認為查詢集應該保持非常簡單,然后您可以在模板中完成大部分工作。

因此,首先,按照您想要的順序進行所有標記,從組開始並更詳細地進行(例如:核心 -> 名稱 -> 季度)。 據我了解,上面的 3 項列表應該非常接近。

然后在您的模板中,使用魔術標簽{% ifchanged %} (請參閱文檔),當表格出現此類問題時,它確實很奇怪。 但是,我會告訴你:模板可能很難閱讀。

無論如何,它應該是這樣的:

<table>
<thead>
  {# Your table headings, quite static, with maybe a loop for quarters #}
</thead>
<tbody>
{% for match in matches %}
    {% ifchanged match.Grading_Behavior__Grading_Behavior__Name %}
        {#  We need a need row for each new name #}
        {% if not forloop.first %}
            {#  Close the previous one if not first loop #}
            </tr>
        {% endif %}
        <tr>
    {% endifchanged %}

    {# First, your group name  #}
    {% ifchanged match.Grading_Behavior__Grading_Behavior__GroupName %}
        <td rowspan="2" colspan="4" class="tblcoretitle">
            {{ match.Grading_Behavior__Grading_Behavior__GroupName }}
       </td>
    {% endif %}

    {# First, then the name  #}
    {% ifchanged match.Grading_Behavior__Grading_Behavior__Name %}
        <td colspan="4" class="tblcore">
            {{ match.Grading_Behavior__Grading_Behavior__Name }}
       </td>
    {% endif %}

    {# Then your marking #}
    <td class="tblcore">{{match.Marking.Marking}}</td>

    {% if forloop.last %}
        {# Close the last row in the last loop #}
        </tr>
    {% endif %}
{% endfor %}
</tbody>
</table>

這可能不太正確,但是一旦你掌握了 ifchanged 的​​竅門,並且你專注於它呈現的標記,你應該沒問題。

另外不要忘記您可以在{% for %}使用的變量, 請參閱文檔

暫無
暫無

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

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