繁体   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