使用Django Listview,是否可以显示包含楼层划分和模数值的新列?
我有以下两种模式:
class Model_Item(models.Model):
item_name = models.CharField(max_length = 100, null = False, blank = False, unique = True)
item_bottleperpack = models.FloatField(null = True, blank = False) # e.g. 100 bottles per pack
def __unicode__(self):
return self.item_name
class Model_ItemTransaction(models.Model):
item = models.ForeignKey(Model_Item, to_field = "item_name")
item_sold = models.FloatField(null = True, blank = True) # in terms of bottle
def __unicode__(self):
return self.item
使用此列表视图:
class View_Item(ListView):
def get_queryset(self):
queryset = Model_Item.objects.all()
queryset = queryset.annotate(
sum_ = Sum("model_itemtransaction__item_sold")
)
queryset = queryset.annotate(
floor_division_ = F("sum_") // F("item_bottleperpack"),
module_ = F("sum_") %% F("item_bottleperpack")
)
return queryset
基本上,如果我已售出650瓶,每包装100瓶,我希望列表视图显示:
目前,我的当前代码
收到以下错误unsupported operand type(s) for //: 'F' and 'F'
and
unsupported operand type(s) for %%: 'F' and 'F'
并希望有人可以帮我找到任何解决方案(而且不一定是conditional expression)。
答案 0 :(得分:0)
您可以在Model_Item中创建一个新的floor_division和module_字段,然后使用post save receiver更新floor_division和module_字段
from django.db.models.signals import pre_save
class Model_Item(models.Model):
item_name = models.CharField(max_length = 100, null = False, blank = False, unique = True)
item_bottleperpack = models.FloatField(null = True, blank = False) # e.g. 100 bottles per pack
floor_division = models.IntegerField(null=True, blank=True)
module_ = models.IntegerField(null=True, blank=True)
def __unicode__(self):
return self.item_name
def model_item_pre_save(sender, instance, created):
item = Model_Item.objects.get(id=instance.id)
item_transaction = Model_Transaction.objects.get(item_id=instance.id)
item.floor_division = item_transaction.item_sold // item.item_bottleperpack
item.module_ = item_transaction.item_sold %% item.item_bottleperpack
pre_save.connect(model_item_pre_save, sender=Model_Item)
答案 1 :(得分:0)
根据https://docs.djangoproject.com/en/2.0/_modules/django/db/models/expressions/:
课程F
或其父Combinable
都未实施__floordiv__
,因此//
未实施。 Combinable
确实实施了__truediv__
,即/
运营商。
我还没有听说过Python中的运算符%%
,但%
会有效,因为__mod__
中已实现Combinable
。
尝试对models.IntegerField
和models.PositiveIntegerField
使用item_bottleperpack
或item_sold
,并在views.py中更新此行:
queryset = queryset.annotate(
floor_division_ = F("sum_") / F("item_bottleperpack"),
module_ = F("sum_") % F("item_bottleperpack")
)
我假设Combinable将返回一个整数作为除以两个整数的输出 - 这可能不是这种情况。如果是这样,您可能想要舍入结果。
答案 2 :(得分:0)
所以我找到了解决这个问题的方法,感谢这个post。
首先我清理了views.py,
中的代码class View_Item(ListView):
def get_queryset(self):
queryset = Model_Item.objects.all()
queryset = queryset.annotate(
sum_ = Sum("model_itemtransaction__item_sold")
)
return queryset
然后将此代码文件添加到templatetags文件夹中,
from django import template
register = template.Library()
@register.filter(name = "func_floor_division")
def func_floor_division(num, val):
if num:
floor_division = num // val
return floor_division
else:
return None
@register.filter(name = "func_modulo")
def func_modulo(num, val):
if num:
modulo = num % val
return modulo
else:
return None
最后修改了html文件中的标签。
{% load app_filters %}
<table>
<tr>
<th>Floor Division</th>
<th>Modulo</th>
</tr>
{% for obj_ in object_list %}
<tr>
<td>{{ obj_.sum_|func_floor_division:obj_.item_bottleperpack }}</td>
<td>{{ obj_.sum_|func_modulo:obj_.item_bottleperpack }}</td>
</tr>
{% endfor %}
</table>
希望这对遇到同样问题的人有所帮助。