[英]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 个或更多查询集。
您可以OR或AND它们, 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=[])
您希望将匹配对象指向具有如下形状的匹配列表:
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 %}
这会让你得到你想要的结果。
您的问题有一个非常简单的解决方案,它不在查询集区域(有点)。
根据您告诉我们的内容,您正在尝试按以下顺序对每个结果进行分组:
我认为查询集应该保持非常简单,然后您可以在模板中完成大部分工作。
因此,首先,按照您想要的顺序进行所有标记,从组开始并更详细地进行(例如:核心 -> 名称 -> 季度)。 据我了解,上面的 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.