【问题标题】:django: calculate percentage based on object countdjango:根据对象计数计算百分比
【发布时间】:2013-10-17 16:27:41
【问题描述】:

我有以下型号:

class Question(models.Model):
    question = models.CharField(max_length=100)

class Option(models.Model):
    question = models.ForeignKey(Question)
    value = models.CharField(max_length=200)

class Answer(models.Model):
    option = models.ForeignKey(Option)

每个Question 都有用户定义的Options。例如:问题 - 什么是最好的水果?选项 - 苹果、橙子、葡萄。现在其他用户可以Answer 提问,他们的回答仅限于Options

我有以下看法:

def detail(request, question_id):
    q = Question.objects.select_related().get(id=question_id)
    a = Answer.objects.filter(option__question=question_id)
    o = Option.objects.filter(question=question_id).annotate(num_votes=Count('answer'))
    return render(request, 'test.html', {
        'q':q, 
        'a':a,
        'o':o,
    })

对于 o 中的每个选项,我都会收到一个答案计数。例如:

问题 - 什么是最好的水果?
选项 - 葡萄、橙子、苹果
答案 - 葡萄:5 票,橙 5 票,苹果 10 票。

计算每个选项在该问题总票数中的投票百分比的最佳方法是什么?

换句话说,我想要这样的东西:

答案 - 葡萄:5 票 25% 票,橙子 5 票 25% 票,苹果 10 票 50% 票。

test.html

{% for opt in o %}
     <tr>
         <td>{{ opt }}</td>
     <td>{{ opt.num_votes }}</td>
     <td>PERCENT GOES hERE</td>
</tr>
 {% endfor %}

 <div>
     {% for key, value in perc_dict.items %}
         {{ value|floatformat:"0" }}%
     {% endfor %}
 </div>

【问题讨论】:

    标签: python django django-models django-templates aggregate


    【解决方案1】:

    试试这个

    total_count = Answer.objects.filter(option__question=question_id).count()
    perc_dict = { }
    for o in q.option_set.all():
        cnt = Answer.objects.filter(option=o).count()
        perc = cnt * 100 / total_count
        perc_dict.update( {o.value: perc} )
    
    #after this the perc_dict will have percentages for all options that you can pass to template.
    

    更新:向查询集添加属性并不容易,也不可能在模板中使用键作为变量来引用字典。

    因此解决方案是在Option 模型中添加方法/属性以获取百分比为

    class Option(models.Model):
        question = models.ForeignKey(Question)
        value = models.CharField(max_length=200)
        def get_percentage(self):
            total_count = Answer.objects.filter(option__question=self.question).count()
            cnt = Answer.objects.filter(option=self).count()
            perc = cnt * 100 / total_count
            return perc
    

    然后在模板中你可以通过所有这些方法来获取百分比为

    {% for opt in o %}
         <tr>
             <td>{{ opt }}</td>
         <td>{{ opt.num_votes }}</td>
         <td>{{ opt.get_percentage }}</td>
    </tr>
     {% endfor %}
    

    【讨论】:

    • 抱歉,我不完全了解如何将其集成到我现有的代码中。我应该用这个代替我认为的一切吗?我将如何在我的模板中显示它?
    • 我已更新我的问题以显示我的模板。您的解决方案有效,但它似乎与我的模板中的内容不同..
    • 是创建一个方法还是在视图中创建一个列表更好?例如[(Option1, 2votes, 50%), (option2, 2votes, 50%)]
    • @thedeepfield,我认为模型上的方法更好/更干净,唯一的问题是它为每个选项计算 total_count。创建 dicts/list 列表也是一种好方法,但是如果将新属性添加到需要在模板中显示的模型中,则必须修改该代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-14
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 2014-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多