我正在努力设计django应用程序.鉴于以下型号:
class A(models.Model): name = models.CharField(max_length=255) class B(models.Model): name = models.CharField(max_length=255) a = models.ForeignKey(A) class C(models.Model): val = models.IntegerField() b = models.ForeignKey(B)
我想要一个视图/模板,显示一个HTML表,在第一列显示所有A对象,在第二列中显示所有B对象(按A分组)引用A,在最后一列显示所有val的总和每个B引用的C对象.所有这些都包含每个A对象的总和.以下示例显示了我正在寻找的内容:
A1.name | B1.name [where FK to A1] | sum(C.val) [where FK to B1] A1.name | B2.name [where FK to A1] | sum(C.val) [where FK to B2] A1.name | Total | sum(C.val) [where FK to Bx (all B that have FK to A1] A2.name | B3.name [where FK to A2] | sum(C.val) [where FK to B3] A2.name | Total | sum(C.val) [where FK to Bx (all B that have FK to A2]
任何人都可以给我一个如何设计这样一个问题的建议(不幸的是,我的代码经常会陷入混乱)?
我应该使用适当的方法扩展模型类吗?在视图中对整个表数据执行自定义查询?只需通过经理获取所有对象并完成模板中的大部分操作?
谢谢你的每一个答案.
问候,
卢克.
如果您有该日期模型,那么您可以获取所有b
s,然后将它们分组a
并计算总金额.代码可能如下所示:
视图:
from django.utils.itercompat import groupby def view(request): bs = B.objects.all().annotate(sum_of_c_val=Sum('c.val'))\ .select_related('a') b_by_a = [ { 'grouper': key, 'list': list(val), 'total': sum([b.sum_of_c_val for b in val]) } for key, val in groupby(bs, lambda b: b.a) ] return render_to_response('tmpl.html', {'b_by_a': b_by_a})
和模板:
{% for b_group in b_by_a %} {% for b in b_group.list %}{% endfor %} {{b_group.grouper.name}} {{b.name}} {{b.sum_of_c_val}} {% endfor %} {{b_group.grouper.name}} Total {{b_group.total}}
编辑:
为了与Django 1.0兼容,您必须annotate
使用extra
select或in-python amount计算替换调用.
使用子查询:
bs = B.objects.all().extra( select={ 'sum_of_c_val': 'SELECT SUM(app_c.val) FROM app_c WHERE app_c.b_id=app_b.id' }).select_related('a') #...
Where app
- 应用程序名称
这个in-python计算:
bs = B.objects.all().select_related('a') for b in bs: b.sum_of_c_val = sum(map(int, b.c.all().values_list("val", flat=True))) #...
但它会产生N个额外的查询(其中N = len(bs)
)