Django: data from context not displaying in template

Viewed 102

I wrote a view to display top selling course, and then passed the data to the context dict to be able to access it in the template, but no data is showing in the template when I run a forloop on the queryset.

views.py:

@login_required
def dashboard(request):
    ...

    course_counts = UserCourse.objects.values("course").annotate(count=models.Count("course")).filter()
    sorted_courses = sorted(course_counts, key=lambda x: x['count'],reverse=True)
    
    
    context = {
        'course_counts':course_counts,
        'sorted_courses':sorted_courses,
    }
    return render(request, 'dashboard/dashboard.html', context)

dashboard.html:

{% for course in sorted_courses %}
    <h1>{{ course.course_title }}</h1>
{% endfor %}

models.py:

class Course(models.Model):
    course_title = models.CharField(max_length=100, null=True, blank=True)
    course_creator = models.ForeignKey(User, on_delete=models.CASCADE)


class UserCourse(models.Model):
    user = models.ForeignKey(User , null = False , on_delete=models.CASCADE)
    course = models.ForeignKey(Course , null = False , on_delete=models.CASCADE, related_name="usercourse")

1 Answers

When you called .values() you changed objects to QuerySet of directories with only course key and its value under field with that name. Basically it looks like this:

<QuerySet [{"course": "some value"}, {"course": "another value"}, {"course": "another value"} {...}]>

Then you make some more stuff and you try to operate them as they were objects. They are not the objects you want. Just to see what's there try changing that loop to:

{% for course in sorted_courses %}
    <h1>{{ course }}</h1>
{% endfor %}

And I think you will understand the rest. You can always call the dictionary values inside the loop. Seeing what you have done I assume you may try:

{{ course.course }}
# or
{{ course.count }}

But I don't think this was what you wanted. If you want to stay with database objects, use .filter() or .order_by() methods. But remember, that empty .filter() method does literally nothing.

Related