外键模型的django计数

Posted

技术标签:

【中文标题】外键模型的django计数【英文标题】:django count of foreign key model 【发布时间】:2016-01-05 01:27:02 【问题描述】:

您好,我想显示我的问题模型的答案计数

我的模特:

class Question(models.Model):

    text = models.TextField()
    title = models.CharField(max_length=200)
    date = models.DateTimeField(default=datetime.datetime.now)
    author = models.ForeignKey(CustomUser)
    tags = models.ManyToManyField(Tags)

    def __str__(self):
        return self.title


class Answer(models.Model):

    text = models.TextField()
    date = models.DateTimeField(default=datetime.datetime.now)
    likes = models.IntegerField(default=0)
    author = models.ForeignKey(CustomUser)
    question = models.ForeignKey(Question)

我的看法:

def all_questions(request):

    questions = Question.objects.all()
    answers = Answer.objects.filter(question_id=questions).count()

    return render(request, 'all_questions.html', 
            'questions':questions, 'answers':answers )

现在视图显示所有答案的计数。我如何通过Question 模型过滤它?

【问题讨论】:

如果您想在 Django Admin 中使用此功能,请参阅 ***.com/a/4547426/148439 annotate 方法的精彩展示 【参考方案1】:

您可以使用.annotate()获取与每个question关联的answers的计数。

from django.db.models import Count
questions = Question.objects.annotate(number_of_answers=Count('answer')) # annotate the queryset

通过这样做,每个question 对象将有一个额外的属性number_of_answers,其值answers 与每个question 相关联。

questions[0].number_of_answers # access the number of answers associated with a question using 'number_of_answers' attribute

最终代码:

from django.db.models import Count

def all_questions(request):
    questions = Question.objects.annotate(number_of_answers=Count('answer'))
    return render(request, 'all_questions.html', 
            'questions':questions)

在您的模板中,您可以执行以下操作:

% for question in questions %
    question.number_of_answers # displays the number of answers associated with this question

【讨论】:

【参考方案2】:

见docs 您可以对查询进行注释,例如:

from django.db.models import Count
questions = Question.objects.annotate(num_answer=Count('answer'))

但是,将代码重构为此。 删除答案计数:

def all_questions(request):
    questions = Question.objects.all()
    return render(request, 'all_questions.html', 'questions':questions )

现在,在all_question.html。只需使用:

% for question in questions %
    Title: question.title
    Count Answers: question.answer_set.all|length
    % for answer in question.answer_set.all %
        answer.text
    % endfor %
% endfor %

效率更高。

【讨论】:

谢谢你,它成功了!我使用第二个建议。但我不了解 Count,我需要在我的 Question 模型中添加这个字段? 在这种情况下你不需要使用注释.. 只需在 html 上使用长度 我这样做了,它奏效了。如果我问愚蠢的问题,我很抱歉,只是试图了解 Count 的工作原理。据我了解,如果我在我的模型中添加计数字段,例如count = Question.objects.annotate(num_answer=Count('answer')),我可以在我的模板中使用它 question.count 您不需要在模型中添加字段计数,即 'annotate' 。当指定 annotate() 子句时,QuerySet 中的每个对象都将使用指定的值进行注释。 您好@PauloPessoa 与第一个答案相比,您的解决方案有什么性能优势吗?谢谢!

以上是关于外键模型的django计数的主要内容,如果未能解决你的问题,请参考以下文章

如何向具有多对一关系的模型的 Django 管理员添加可排序的计数列?

Django 多注解返回错误结果

Laravel 关系多对多按外键计数相关数据

在 Django 中有效地获取相关模型的计数

Django - 每个不同状态的查询计数

Django聚合,计数总和