ListView Джанго - Как настроить его - PullRequest
0 голосов
/ 07 марта 2019

Прошу прощения, если это дубликат, но я не нашел ответа на свой вопрос.

Моя проблема ниже

Я действительно изо всех сил пытаюсь понятьКак настроить мои представления при использовании ListView.Я читаю документацию по Django, но нахожу ее очень краткой.

Я бы хотел сосчитать вопросы по каждой теме и вернуть тему с наибольшим количеством вопросов.Я мог бы подсчитать количество вопросов по каждой теме со следующей строкой кода в моем models.py (класс темы):

def questions_count(self):
    return Question.objects.filter(question__topic = self).count()

Однако я хотел бы вернуть только самую популярную темуи количество вопросов.

Используя представление на основе функций, я бы перебирал темы и создавал две переменные, хранящие название темы и количество вопросов.Однако с ListView я не знаю, использовать ли get_context_data (), get_queryset () или что-то еще.

Мой класс просмотра :

class TopicsView(ListView):
    model = Topic
    context_object_name = 'topics'
    template_name = 'home.html'

Мои модели :

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)    
    ....

Ответы [ 2 ]

1 голос
/ 07 марта 2019

Возможно, вы захотите попробовать .annotate(), чтобы получить счетчик Questions, связанный с каждым Topic:

from django.db.models import Count

topics_count = Topics.objects.annotate(count_of_questions=Count('question'))

Каждый Topic объект будет иметь новый атрибут count_of_questions, который представляет собой общее количество вопросов, связанных с каждым Topic.

В вашем 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'))

Тогда вы сможете использовать dictsortreversed для выполнения следующих действий в вашем шаблоне, которые должны вернуть тему с наибольшим количеством вопросов first :

{% for t in topics|dictsortreversed:"count_of_questions" %}
    {{ t.count_of_questions }}
{% endfor %}

Есть аналогичный вопрос и ответ в следующем SO Q & A

0 голосов
/ 07 марта 2019

В конце концов мне удалось сделать это с помощью функции get_context_data ().Вот как выглядит мое решение:

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)

    mostQuestions = context['object_list'][0].questions_count()
    mostQuestionsTopic = context['object_list'][0]

    for topic in context['object_list']:
        if topic.questions_count() > mostQuestions:
            mostQuestions = topic.questions_count()
            mostQuestionsTopic = topic

    context['mostQuestions'] = mostQuestions
    context['mostQuestionsTopic'] = mostQuestionsTopic

    return context

Есть ли более эффективное решение?

...