Django 尝试创建一种有效的方法来生成具有组合结果的交叉联接

Django 尝试创建一种有效的方法来生成具有组合结果的交叉联接,django,python-3.x,django-orm,cross-join,Django,Python 3.x,Django Orm,Cross Join,假设我们有这些模型: class ClassRoom(models.Model): name = models.CharField(max_length=255) class Student(models.Model): name = models.CharField(max_length=255) classroom = models.ForeignKey(ClassRoom...... class Course(models.Model):

假设我们有这些模型:

class ClassRoom(models.Model):
      name = models.CharField(max_length=255)

class Student(models.Model):
      name = models.CharField(max_length=255)
      classroom = models.ForeignKey(ClassRoom......

class Course(models.Model):
      name = models.CharField(max_length=255)

class Grades(models.Model):
      student = models.ForeignKey(Student....
      course = models.ForeignKey(Course....
      grade = models.CharField(.....
我想创建课程和学生的交叉连接,但表中有分数

|          | Student A | Student B |
| Course 1 | 8         |           |
| Course 2 | 6         | 4         |
请注意,学生B尚未获得课程1的分数

我现在是这样解决的

query = list(product(courses, students)
grades = Grades.objects.all.....
for i, query_tuple in enumerate(query):
     grade = grades.filter(query_tuple[0], query_tuple[1]
     if grade: # Note 1
         # Here I add it to a list of the grades
但在“#注1”中,它每次都会运行一个查询,这大大降低了性能(一个班级最多可以有30名学生,每门课程超过50门)


有更好的方法吗?也许更多的是Django ORM风格?

是的。请不要对每个表单元格进行查询。这通常不是个好主意

我们可以先查询
课程
s和
学生
s,然后制作一个2d列表,如:

courses = Course.objects.all()
students = Student.objects.filter(classroom=classroom)

coursemap = { c.pk: i for i, c in enumerate(courses) }
studentmap = { s.pk: i for i, s in enumerate(students)}

table = [[None] * len(student) for __ in range(len(courses))]

for grade in Grade.objects.filter(student__classroom=classroom):
    row = coursemap.get(grade.course_id)
    col = coursemap.get(grade.student_id)
    if row is not None and col is not None:
        table[row][col] = grade.grade
然后将其渲染为:

<table>
    <thead>
        <tr>
            <th>&times;</th>
            {% for student in cols %}
                <th>{{ student.name }}</th>
            {% endfor %}
        </tr>
    </thead>
    <tbody>
        {% for course, grades in rows %}
            <tr>
                <th>{{ course.name }}</th>
                {% for grade in grades %}
                    <td>{{ grade|default_if_none:'' }}</td>
                {% endfor %}
            </tr>
        {% endfor %}
    </tbody>
</table>

&时代;
{cols%中的学生百分比}
{{student.name}
{%endfor%}
{课程分数为%,第%}
{{course.name}
{分数%中的分数为%}
{{grade}默认值{u如果没有:'}
{%endfor%}
{%endfor%}

但是,您可以使用来完成这项工作并删除样板代码。

在过去的30分钟里,我一直在尝试让这项工作正常进行,但我似乎无法解决这个问题。我得到了一个填充表,这是伟大的,就像我已经非常感谢你了!但是,当试图在模板中显示表格时遇到问题,当表格中只有ID时,如何打印课程/学生姓名?你通常不能从pk中返回对象,对吗?写一个函数来得到你推荐的对象吗?@MrDikke:应该是更新答案中的模板。是的,我想我不会教你这个!非常感谢你!
<table>
    <thead>
        <tr>
            <th>&times;</th>
            {% for student in cols %}
                <th>{{ student.name }}</th>
            {% endfor %}
        </tr>
    </thead>
    <tbody>
        {% for course, grades in rows %}
            <tr>
                <th>{{ course.name }}</th>
                {% for grade in grades %}
                    <td>{{ grade|default_if_none:'' }}</td>
                {% endfor %}
            </tr>
        {% endfor %}
    </tbody>
</table>