I am sorry if this is a duplicate, but I did not find any answer to my question.
My issue below
I am really struggling to understand how to customise my views when using ListView. I read the Django documentation, but I find it very brief.
What I would like to do is to count the questions for each topic and return the topic with the most questions. I would be able to count the number of questions for each topic with the following line of code in my models.py (Topic class):
def questions_count(self):
return Question.objects.filter(question__topic = self).count()
However, I would like to return only the most popular Topic and the number of questions.
Using a function-based view, I would loop over the topics, and I would create two variables storing the topic name and the number of questions. However, with the ListView I do not know whether to use get_context_data(), get_queryset() or something else.
My view class:
class TopicsView(ListView):
model = Topic
context_object_name = 'topics'
template_name = 'home.html'
My models:
class Topic(models.Model):
name = models.CharField(max_length=30, unique=True)
description = models.CharField(max_length=100)
class Question(models.Model):
....
topic = models.ForeignKey(Topic, related_name='questions', on_delete=models.CASCADE)
....
You might want to try using .annotate()
to get the count of Questions
associated with each Topic
:
from django.db.models import Count
topics_count = Topics.objects.annotate(count_of_questions=Count('question'))
Each Topic
object will have a new attribute count_of_questions
which is the total number of questions associated with each Topic
.
In your ListView
:
class TopicsView(ListView):
model = Topic
context_object_name = 'topics'
template_name = 'home.html'
def get_queryset(self):
queryset = super(TopicsView, self).get_queryset()
queryset = queryset.annotate(count_of_questions=Count('question'))
Then you should be able to use dictsortreversed to do the following in your template, which should return the topic with the most questions first:
{% for t in topics|dictsortreversed:"count_of_questions" %}
{{ t.count_of_questions }}
{% endfor %}
There's a similar question and answer in the following SO Q&A