Django结合3个查询集

5 python django

朋友们好,我不太熟悉将查询集合并为一个。如何在不改变模板设计的情况下达到我想要的结果?

注意:我已经问过这个问题了。我刚刚发现在 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)
Run Code Online (Sandbox Code Playgroud)

这是我的 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 %}
Run Code Online (Sandbox Code Playgroud)

这是我的StudentsBehaviorGrades管理站点视图:

在此处输入图片说明

这是我目前的结果:

在此处输入图片说明

我想要结果:

在此处输入图片说明

更新

当我在我的 views.py 中尝试这个时:

matches = set(itertools.chain(cores, behaviors,Marking))
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

在此处输入图片说明

伙计,如果您有更好的解决方案或想法,请分享您的答案。

这就是我渲染的方式

    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,})
Run Code Online (Sandbox Code Playgroud)

Ahm*_*yed 7

Combining querysets is very straight forward. You have two options when combining which SOMTIMES act like if they're the same.

Models deeply are just raw SQL statements, Combinations in SQL happen with AND or OR , Which exist in python. There're Q objects for more complex look ups. Let's see.

If you have 2 querysets or more.

You can OR or AND them, qs_3 = qs_1 & qs_2 will return both of them concatenated IF THEY ARE OF THE SAME TYPE

Same with |, However, you have different types, That's why Q objects exist.

e.g

from django.db.models import Q
my_concatenated_qs = Q(MyModel__my_attr_if_I_want="") & Q(MyAnotherModel)  
Run Code Online (Sandbox Code Playgroud)

| works too.

NOTE: MyModel, MyAnotherModel is not a model instance, It's just the name, not a string too. Just the raw name without quotes.

You can also remove the my_attr_if_I_want, I just wanted to show it's possible to use the __ syntax here.

Q objects are not limited to model queries like I've shown

e.g

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')
)
Run Code Online (Sandbox Code Playgroud)

You can also negate querysets

e.g

X = True
Y = not X
Run Code Online (Sandbox Code Playgroud)

This is Negation, To negate Q objects (NOT query)

~Q(MyModel__startswith="A") | Q(MyModel__whatever__whatever=[])
Run Code Online (Sandbox Code Playgroud)

Further more, You can read about Q objects here