Reshape django queryset to display in template

I am learning Django and trying to build a simple student grade publishing system. I have set up my model classes as follow:

class Student(models.Model):
    name= models.CharField(max_length=30)
    rollNum=models.CharField(max_length=12)
    faculty=models.CharField(max_length=10)
    def __str__(self):
        return self.name

class Tutorial(models.Model):
    name=models.CharField(max_length=10)
    def __str__(self):
        return self.name

class Grade(models.Model):
    grade=models.CharField(max_length=2)
    student=models.ForeignKey(Student,on_delete=models.CASCADE)
    tutorial=models.ForeignKey(Tutorial,on_delete=models.CASCADE)
    def __str__(self):
        return self.student.name+ '|' + self.tutorial.name+ '|' +self.grade  
    class Meta:
        unique_together = ('student','tutorial')

Grade.objects.filter().values_list('student__name','tutorial__name','grade') is returning QuerySet in following form:

Student1 Tutorial1 A
Student2 Tutorial1 A+
Student1 Tutorial2 B
Student1 Tutorial3 A

How can I reshape the result into the following form?

Student Tutorial1 Tutorial2 Tutorial 3
Student1     A       B         A
Student2     A+      X         X

I want to render this in django template.

Edit: My view

def results(request):
    grades=Grade.objects.filter().values_list('student__name','tutorial__name','grade')
    return render(request,'results/index.html',{"a":grades})

Earlier, I tried to simplify the data sent to the template in following form:

{'Student1': {'Tutorial1': 'A', 'Tutorial1': 'A'}, 'Student2': {'Tutorial2': 'A'}, 'Student3': {'Tutorial1': 'A', 'Tutorial1': 'A'}}

using following code in views.py

def results(request):
    grades=Grade.objects.filter().values_list('student__name','tutorial__name','grade')
    dic1=defaultdict(list)
    dic2=defaultdict(list)
    for s,t,g in grades:
        if t not in dic1:
            dic1[t]=g
        dic2[s]=dict(dic1)
    return render(request,'results/index.html',{"a":dict(dic2)})

Unfortunately I couldn't come up with a logic to use the data returned into the template

1 answer

  • answered 2020-06-27 06:35 Abhishek bansal

    You can do something like(after you have created the dictionary) in your templates-

    {% for st in a.keys %}
    // st is the student name
    {{ st }}
    {% for tut in a[st].keys %}
    // tut is tutorial name and a[st][tut] is the grade
    {{ tut }}
    {{ a[st][tut] }}
    {% endfor %}
    {% endfor %}
    

    Place them appropriately in table.