在表设计问题中显示多个相关的Django模型
我正在努力设计django应用程序。鉴于以下模型:在表设计问题中显示多个相关的Django模型,django,django-models,Django,Django Models,我正在努力设计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()
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分组),并在最后一列中显示每个B引用的所有C对象val的总和。所有这些都包含每个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]
A1.name | B1.name[其中FK到A1]| sum(C.val)[其中FK到B1]
A1.name | B2.name[其中FK到A1]| sum(C.val)[其中FK到B2]
A1.name | Total | sum(C.val)[其中FK到Bx(所有具有FK到A1的B]
A2.name | B3.name[其中FK到A2]| sum(C.val)[其中FK到B3]
A2.name | Total | sum(C.val)[其中FK到Bx(所有具有FK到A2的B]
有人能给我一个如何设计这样一个问题的建议吗(不幸的是,我的代码经常以一团糟告终)
我应该用适当的方法扩展模型类吗?对视图中的整个表数据执行自定义查询吗?只需通过管理器获取所有对象并在模板中执行大部分操作即可
谢谢你的回答
问候,
卢克。免责声明:我自己也是Django初学者,但如果我正确理解了它的基本概念,那么:
假设您想要的视图(如您所说)只是底层数据的视图,那么您应该在视图模块中进行排序和分组。我认为您不应该弄乱模型(这只是数据),也不应该弄乱模板(这只是视图的布局).如果您有该日期模型,因此可以获取所有
b
s,然后按a
对它们进行分组并计算总金额。代码可能如下所示:
视图:
和模板:
{% for b_group in b_by_a %}
{% for b in b_group.list %}
<tr>
<td>{{b_group.grouper.name}}</td>
<td>{{b.name}}</td>
<td>{{b.sum_of_c_val}}</td>
</tr>
{% endfor %}
<tr>
<td>{{b_group.grouper.name}}</td>
<td>Total</td>
<td>{{b_group.total}}</td>
</tr>
{% endfor %}
其中应用程序
-应用程序名称
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)
)谢谢,这看起来比我提出的要干净得多,但这只适用于Django v1.1和更高版本,对吗?是的,由于聚合,它与当前主干和未来版本兼容。您可以用
额外的选择(子查询)或在python中为每个B
计算C.val
金额
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')
#...
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)))
#...