【发布时间】:2016-05-29 20:26:35
【问题描述】:
我想在一张桌子上显示我所展示的资产的总重量。
每个资产都有重量和数量,我可以将每个资产的总重量显示如下:
def by_item_weight(self):
"""This Method gives the total value of the asset. Weight * Qnty"""
total = self.asset_quantity * self.asset_weight
return total
我想要做的是获取每个资产的总重量(数量 * 重量的结果)并呈现所有资产的总重量。
我尝试对以下进行各种组合以返回 by_item_weight“列”的总和:
Asset.objects.all().annotate(total=Sum('by_item_weight')
但我知道这不起作用,因为模型资产中未定义按项目重量。
我在 assetslist.html 模板上通过如下的 for 循环展示表格:
{% block content %}
<table class="well table table-striped text-center">
<thead>
<tr class="text-center">
<th class="text-center">Asset ID:</th>
<th class="text-center">Asset Name:</th>
<th class="text-center">Asset Quantity:</th>
<th class="text-center">Asset Weight / kg:</th>
<th class="text-center">Total Weight / kg:</th>
<th class="text-center">Asset Owner:</th>
</tr>
</thead>
<tbody>
<tr class="text-center">
{% for asset in object_list %}
<td>{{ asset.id }}</td>
<td>{{ asset.asset_name }}</td>
<td>{{ asset.asset_quantity }}</td>
<td>{{ asset.asset_weight }}</td>
<td>{{ asset.by_item_weight }}</td>
<td>{{ asset.asset_owner }}</td>
</tr>
{% endfor %}
我是 Python 新手,无法找到一种方法来捕获每个asset.by_item_weight 的值,如果我可以在列表中捕获它,我想我可以对列表求和并显示结果。
我的模特
class Asset(models.Model):
asset_name = models.CharField(max_length=30)
asset_quantity = models.IntegerField(default=0)
asset_weight = models.IntegerField(default=0)
asset_owner = models.ForeignKey(
'AssetOwner',
on_delete=models.CASCADE,
) # This should be a Foreign Key Drop down of AssetOwners owner_name.
def by_item_weight(self):
"""This Method gives the total value of the asset. Weight * Qnty"""
total = self.asset_quantity * self.asset_weight
return total
def __str__(self):
return '{}'.format(self.asset_name)
return 'Asset Quantity: {}'.format(self.asset_quantity)
return 'Asset Weight: {}'.format(self.asset_weight)
return 'Asset Owner: {}'.format(self.asset_owner)
return 'Asset Owner: {}'.format(self.asset_owner)
任何帮助将不胜感激。
更新:
现在没有错误,但仍然无法显示/显示 sum_total 的值
新模板
{% extends "personal/header.html" %}
{% block content %}
<h1 class='text-center'>This is the full asset list not split by owner</h1></br>
<table class="well table table-striped text-center">
<thead>
<tr class="text-center">
<th class="text-center">Asset ID:</th>
<th class="text-center">Asset Name:</th>
<th class="text-center">Asset Quantity:</th>
<th class="text-center">Asset Weight / kg:</th>
<th class="text-center">Total Weight / kg:</th>
<th class="text-center">Asset Owner:</th>
</tr>
</thead>
<tbody>
<tr class="text-center">
{% for asset in object_list %}
<td>{{ asset.id }}</td>
<td>{{ asset.asset_name }}</td>
<td>{{ asset.asset_quantity }}</td>
<td>{{ asset.asset_weight }}</td>
<td>{{ asset.by_item_weight }}</td>
<td>{{ asset.asset_owner }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<p class="" style="">Total Weight In Stock : {{ asset.sum_total }}</p>
<p class="text-center">{% include "sam/includes/backtosam.html" %}</p>
{% endblock %}
新模型
from __future__ import unicode_literals
from django.db import models
from django.db.models import Sum, F, Count
from django.db.models import Max
from django.db.models import ExpressionWrapper
from django.db.models import Aggregate
class Asset(models.Model):
asset_name = models.CharField(max_length=30)
asset_quantity = models.IntegerField(default=0)
asset_weight = models.IntegerField(default=0)
asset_owner = models.ForeignKey(
'AssetOwner',
on_delete=models.CASCADE,
) # This should be a Foreign Key Drop down of AssetOwners owner_name.
def by_item_weight(self):
"""This Method gives the total value of the asset. Weight * Qnty"""
total = self.asset_quantity * self.asset_weight
return total
def sum_total(self):
assets = Asset.objects.all().annotate(
total_weight=ExpressionWrapper(F('asset_quantity') * F('asset_weight'),output_field=IntegerField))
the_sum = assets.aggregate(total=Sum('total_weight'))
return the_sum
def __str__(self):
return '{}'.format(self.asset_name)
return 'Asset Quantity: {}'.format(self.asset_quantity)
return 'Asset Weight: {}'.format(self.asset_weight)
return 'Asset Owner: {}'.format(self.asset_owner)
return 'Asset Owner: {}'.format(self.asset_owner)
return 'Total Weight of Assets: {}'.format(self.assets)
更新视图
from django.shortcuts import render
from django.http import HttpResponse
from django.core.cache import cache
from django.db.models import Sum, F
def get_total_weight(self):
total_weight = cache.get('total_weight',-1)
if total_weight == -1:
total_weight = Asset.objects.annotate(total_weight=F('asset_quantity')*F('asset_weight')).aggregate(total=Sum('total_weight'))
# this is tested
cache.set('total_weight',total_weight)
return total_weight
def index(request):
return render(request, 'sam/index.html')
def assetslist(request):
return render(request,'sam/assetslist.html',{'total_weight': get_total_weight}, assets = Asset.objects.all())
我怀疑上述 assetslist 方法存在问题,我显然没有调用它。
模板
{% extends "personal/header.html" %}
{% block content %}
<h1 class='text-center'>This is the full asset list not split by owner</h1></br>
<table class="well table table-striped text-center">
<thead>
<tr class="text-center">
<th class="text-center">Asset ID:</th>
<th class="text-center">Asset Name:</th>
<th class="text-center">Asset Quantity:</th>
<th class="text-center">Asset Weight / kg:</th>
<th class="text-center">Total Weight / kg:</th>
<th class="text-center">Asset Owner:</th>
</tr>
</thead>
<tbody>
<tr class="text-center">
{% for asset in object_list %}
<td>{{ asset.id }}</td>
<td>{{ asset.asset_name }}</td>
<td>{{ asset.asset_quantity }}</td>
<td>{{ asset.asset_weight }}</td>
<td>{{ asset.by_item_weight }}</td>
<td>{{ asset.asset_owner }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<p class="" style="">Total Weight In Stock : {{ get_total_weight }}</p>
<p class="" style="">Total Weight In Stock : {{ assetslist }}</p>
<!-- <table class="well table table-striped text-center">
<thead>
<tr class="text-center">
<th class="text-center"></th>
<th class="text-center"></th>
<th class="text-center"></th>
<th class="text-center"></th>
<th class="text-center">Total Weight / kg:</th>
</tr>
</thead>
<tbody>
<tr class="text-center">
{% for sum_weight in object_list %}
<td></td>
<td></td>
<td></td>
<td></td>
<td>{{ asset.sum_total }}</td>
</tr>
{% endfor %}
</tbody>
</table> -->
<p class="text-center">{% include "sam/includes/backtosam.html" %}</p>
{% endblock %}
感谢您的任何意见/建议。
进一步更新:
我已将视图调整为以下:
from django.core.cache import cache
from django.db.models import Sum, F
def get_total_weight(self):
total_weight = cache.get('total_weight',-1)
if total_weight == -1:
total_weight = Asset.objects.annotate(total_weight=F('asset_quantity')*F('asset_weight')).aggregate(total=Sum('total_weight'))
# this is tested
cache.set('total_weight',total_weight)
return total_weight
render(request,'template_name',{'total_weight': get_total_weight, assets = Asset.objects.all() } )
assets = Asset.objects.all() } ) = 符号出现错误。 SyntaxError: 无效语法
我认为 render 需要在它自己的函数中?
更新:
我已经更新了我的视图并从 models.py 中移动了 def
我的views.py文件如下
def total_weight(request):
assets = Asset.objects.all().annotate(
total_weight=ExpressionWrapper(F('asset_quantity') * F('asset_weight'),
output_field=IntegerField() ))
return render(request, 'sam/index.html')
def sum_total(request):
the_total = assets.aggregate(total=Sum('total_weight'))
return render(request, 'sam/assetlist.html')
def index(request):
return render(request, 'sam/index.html')
def by_item_weight(self):
"""This Method gives the total value of the asset. Weight * Qnty"""
total = self.asset_quantity * self.asset_weight
return total
def get_total_weight(self):
total_weight = Asset.objects.filter(by_item_weight__isnull=True).aggregate(Sum('by_item_weight'))
Asset.objects.annotate(total_weight=F('asset_quantity')*F('asset_weight')).aggregate(total=Sum('total_weight'))
def __str__(self):
return '{}'.format(self.asset_name)
return '{}'.format(self.total_weight)
assetlist.html
下面有一个 JS,我尝试实施以解决这个问题,但也没有用。
在调用views.py中的def值时,我觉得我在assetlist.html上遗漏了一些东西。
{% extends "personal/header.html" %}
{% block content %}
<h1 class='text-center'>This is the full asset list not split by owner</h1></br>
<table id="sum_table" class="well table table-striped text-center">
<thead>
<tr class="text-center titlerow">
<td class="text-center">Asset ID:</td>
<td class="text-center">Asset Name:</td>
<td class="text-center">Asset Quantity:</td>
<td class="text-center">Asset Weight / kg:</td>
<td class="text-center">Total Weight / kg:</td>
<td class="text-center">Asset Owner:</td>
</tr>
</thead>
<tbody>
<tr class="text-center">
{% for asset in object_list %}
<td><a href="/sam/assets/{{ asset.id }}">{{ asset.id }}</></td>
<td>{{ asset.asset_name }}</td>
<td>{{ asset.asset_quantity }}</td>
<td>{{ asset.asset_weight }}</td>
<td class="rowDataSd">{{ asset.by_item_weight }}</td>
<td><a href="/sam/owners/">{{ asset.asset_owner }}</></td>
</tr>
{% endfor %}
<tr class="totalColumn">
<td class=""></td>
<td class=""></td>
<td class=""></td>
<td class=""></td>
<td class="totalCol">Total: {{ asset.get_total_weight }}</td>
<td class=""></td>
</tr>
</tbody>
</table>
<p>Hope this is full ( {{ this_view }} )?</p>
<p class="text-center">{% include "sam/includes/backtosam.html" %}</p>
<!--
<script>
var total = 0;
$('#sum_table tr td.rowDataSd').each(function() {
total += parseInt($(this).text());
});
$('#sum_table td.totalCol').text("total: " + total);
</script>
-->
{% endblock %}
更新 - 2016 年 7 月 3 日
from __future__ import unicode_literals
from django.db import models
from django.db.models import Sum, F, Count
from django.db.models import Max
from django.db.models import ExpressionWrapper
from django.db.models import Aggregate
from django.contrib.auth.models import User
class Asset(models.Model):
asset_name = models.CharField(max_length=30)
asset_quantity = models.IntegerField(default=0)
asset_weight = models.IntegerField(default=0)
total_assets_weight = models.IntegerField(default=0)
asset_owner = models.ForeignKey(
'AssetOwner',
on_delete=models.CASCADE,
) # This should be a Foreign Key Drop down of AssetOwners owner_name.
def by_item_weight(self):
"""This Method gives the total value of the asset. Weight * Qnty"""
total = self.asset_quantity * self.asset_weight
return total
def total_weight(self):
assets = Asset.objects.all().annotate(
total_weight=ExpressionWrapper(F('asset_quantity') * F('asset_weight'),
output_field=IntegerField()))
the_total = assets.aggregate(total=Sum('total_weight'))
return the_total
模板
{% extends "personal/header.html" %}
{% block content %}
<h1 class='text-center'>This is the full asset list not split by owner</h1></br>
<table id="sum_table" class="well table table-striped text-center">
<thead>
<tr class="text-center titlerow">
<td class="text-center">Asset ID:</td>
<td class="text-center">Asset Name:</td>
<td class="text-center">Asset Quantity:</td>
<td class="text-center">Asset Weight / kg:</td>
<td class="text-center">Total Weight / kg:</td>
<td class="text-center">Asset Owner:</td>
</tr>
</thead>
<tbody>
<tr class="text-center">
{% for asset in object_list %}
<td><a href="/sam/assets/{{ asset.id }}">{{ asset.id }}</td>
<td>{{ asset.asset_name }}</td>
<td>{{ asset.asset_quantity }}</td>
<td>{{ asset.asset_weight }}</td>
<td class="rowDataSd">{{ asset.by_item_weight}}</td>
<td><a href="/sam/owners/">{{ asset.asset_owner }}</td>
</tr>
{% endfor %}
{% for total in object_list %}
<tr class="totalColumn">
<td class=""></td>
<td class=""></td>
<td class=""></td>
<td class=""></td>
<td class="totalCol">Total: {{ total.total_weight }}</td>
<td class=""></td>
</tr>
</tbody>
</table>
{% endfor %}
<p class="text-center">{% include "sam/includes/backtosam.html" %}</p>
{% endblock %}
【问题讨论】: