在Django模板中汇总数据库值
我有一个表格,里面有“用户名”和“成绩”。这些成绩的格式是A+、A、A-、B+等等。我想给每个用户显示一个总成绩,用数字表示。比如:
约翰 A+
杰瑞 B+
约翰 C-
汤姆 A-
杰瑞 B+
假设A+等于10分,A等于9分,A-等于8分,依此类推,我该如何计算约翰的总成绩呢?我想在一个DJANGO模板(.html文件)中做到这一点,但我完全不知道怎么实现计数器。
2 个回答
在模板中不能这样做是有原因的。这是因为Django的设计理念是,像这样的逻辑应该放在视图中。
我们把模板系统看作是一个控制展示和与展示相关逻辑的工具,仅此而已。模板系统不应该支持超出这个基本目标的功能。
来源:https://docs.djangoproject.com/en/dev/misc/design-philosophies/#separate-logic-from-presentation
虽然他们确实允许你打破规则,编写自定义标签和过滤器,就像alexcxe说的那样,但把这种逻辑放在视图中并作为上下文变量传递,肯定是更简单的。我不知道你的模型是什么样的,但在这种情况下,使用字典或元组会比较合适。我在类似情况下也做过这两种方式。如果你提供更多细节,我可以给你一个具体的实现建议。
偶尔打破规则是可以的,但我感觉你对Django还不太熟悉,所以在你还不确定什么时候可以打破规则之前,我建议你遵循Django社区设定的规则,特别是如果你想和其他Django开发者一起工作的话。
你可以为这个写一个自己的模板过滤器。首先,在你的模板文件夹里创建一个名为'grade_filters.py'的新python文件,并在一个叫'templatetags'的文件夹里。然后,按照下面的方式声明一个新的模板标签:
from django import template
register = template.Library()
def grade_to_number(grade):
map_dict = {'A+': 10, 'A':9, 'A-':8}
if grade in map_dict:
return map_dict[grade]
else:
return 0
@register.filter(name='sum_of_grades')
def return_item(grade_list):
new_grades_list = [grade_to_number(grade) for grade in grade_list]
try:
return sum(new_grades_list)
except:
return 0
@register.filter(name='get_list_for_student')
def return_item(student_list, name):
return student_list.filter(name=name)
现在,在你的模板中,你可以通过以下方式加载这个新的模板标签:
{% load grade_filters %}
要计算一个学生的总成绩,可以使用:
{{ gradelist|get_list_for_student:'John'|sum_of_grades }}