django - 如何在多个 django 模型上为 Sum() 应用注释?
问题描述
我有三个 django 模型:ProjectName、ProjectBudget 和 ProjectActualCost。
ProjectName 存储项目名称(即项目 X)。
ProjectBudget 存储每个预算的 project_name(作为外键(FK))、budget_name 和 total_budget 和日期。即(项目 X,酒店,600),(项目 X,租赁,500)。“600”是指 600 美元。ProjectActualCost 存储发生的每项成本(分项成本)(即酒店:100,租金:50,食品:100)及其日期。所以它存储了“project_name”(作为 FK)、“budget_name”(作为 FK)、actual_used 和日期。即 (Project X,Hotel,100,10/03/2019),(Project X,Hotel,100,10/06/2019), (Project X,Rental,50,04/10/2019)
我正在尝试在 html 表中呈现“项目名称”、“预算名称”、“总预算”、“总使用量”和“差异”。项目名称”、“预算名称”、“总预算”、“总使用量”正确呈现,但“差异”显示虚增金额,如下所示。
楷模:
class ProjectName(models.Model):
project_name = models.CharField('Name',max_length = 15,blank = False)
def __str__(self):
return self.project_name
class ProjectBudget(models.Model):
project_name = models.ForeignKey(ProjectName,on_delete = models.CASCADE,
null = True)
budget_name = models.CharField('Budget Name'max_length = 50
total_budget = models.DecimalField('Total Budget',max_digits = 9,decimal_places=2)
def __str__(self):
return self.budget_name
class ProjectActualCost(models.Model):
project_name = models.ForeignKey(ProjectName,on_delete = models.CASCADE, null = True)
cost_description = models.ForeignKey(ProjectBudget,on_delete = models.CASCADE,null=True)
actual_used = models.DecimalField('Actual Used',max_digits = 15,decimal_places = 2)
意见:
def budgetview(request,project_id):
budget_items = ProjectBudget.objects.filter(project_name_id=project_id).annotate( actual_cost=Sum('projectactualcost__actual_used'),
difference=Sum('total_budget')-Sum('projectactualcost__actual_used'))
budget_template = "budget_view.html"
context = {"budget_items":budget_items}
return render(request,budget_template,context)
预算视图.html:
<table>
<thead>
<tr>
<th>Project Name</th>
<th>Budget Name</th>
<th>Total Budget</th>
<th>Total Used</th>
<th>Difference</th>
</tr>
<tbody>
{% for item in budget_items%}
<tr>
<td>{{item.project_name}}</td>
<td>{{item.cost_description}}</td>
<td>{{item.total_budget}}</td>
<td>{{item.actual_cost}}</td>
<td>{{item.difference}}</td>
</tr>
{%endfor%}
</tbody>
</table>
我期待看到:
Project Name|Budget Name | Total Budget| Total Used| Difference
Project X Hotel 600 200 400
Project X Rental 500 50 450
但是当我渲染budget_view.html 时,我得到:
Project Name|Budget Name | Total Budget| Total Used|Difference|
Project X | Hotel | 600 | 300 | 900
Project X | Rental | 500 | 100 | 600
我如何正确计算多个 sum() 注释?谢谢。
解决方案
这是行不通的,因为您正在聚合 ProjectBudget 表中的所有行。尝试添加一个属性来处理每个 ProjectBudget 实例的差异计算。
class ProjectBudget(models.Model):
project_name = models.ForeignKey(ProjectName, on_delete=models.CASCADE,
null=True)
budget_name = models.CharField('Budget Name', max_length=50)
total_budget = models.DecimalField('Total Budget', max_digits=9, decimal_places=2)
def __str__(self):
return self.budget_name
@property
def used_difference(self):
return self.total_budget - self.projectactualcost_set.filter(cost_description=self.id)\
.aggregate(Sum('actual_used')).get('actual_used__sum')
并更新模板
<table>
<thead>
<tr>
<th>Project Name</th>
<th>Budget Name</th>
<th>Total Budget</th>
<th>Total Used</th>
<th>Difference</th>
</tr>
<tbody>
{% for item in budget_items %}
<tr>
<td>{{ item.project_name }}</td>
<td>{{ item.budget_name }}</td>
<td>{{ item.total_budget }}</td>
<td>{{ item.actual_cost }}</td>
<td>{{ item.used_difference }}</td>
</tr>
{% endfor %}
</tbody>
</table>
这给了我
Project Name|Budget Name | Total Budget| Total Used|Difference|
Project X | Hotel | 600 | 250 | 350
Project X | Rental | 500 | 100 | 400
推荐阅读
- javascript - 在 Angular 中急切地加载图像
- r - 时间范围 08:00:00 和 15:00:00 之间的采样时间
- gtk - 开罗没有在 GtkTreeView 上绘图
- javascript - JS 模块 vs 脚本加载顺序,Safari 中的全局变量
- javascript - 无法将对象数组从父组件传递到子组件
- php - 如何将html放入else
- javascript - 页面加载后是否可以更改css样式表?
- azure-devops - 在 Azure DEVOPS 中预先批准后手动部署
- c# - UWP 响应控制宽度变化
- ruby-on-rails - Rails 上的 parselyjs 和 webpack