python - 如何对 django get_context_data() 中的 2 列求和
问题描述
我想在 ClassBasedView 的 get_context_data 方法中将总值作为收入变量返回。
我还想返回另一个操作:total
-shipping_cost
作为revenue_no_shipping_cost
上下文中的变量。
我试过了:
from django.db.models import F, Sum
class OrdersListView(PermissionRequiredMixin,ListView):
model = Order
permission_required = 'is_staff'
template_name = "order/revenue.html"
paginate_by = 10
def get_queryset(self):
filter_month = self.request.GET.get('filtromes', '0')
if filter_month == "0":
return Order.objects.filter(status = 'recibido_pagado')
else:
return (Order.objects
.filter(created__month=filter_month, status = 'recibido_pagado'))
def get_context_data(self, **kwargs):
context = super(OrdersListView, self).get_context_data(**kwargs)
qs = kwargs.pop('object_list', self.object_list)
order = self.request.GET.get('orderby', 'created')
context = {}
revenue = qs.aggregate(revenue=Sum('total'))
revenue_no_shipping = qs.annotate(revenue_no_shipping=F('total') + F('shipping_cost'))
context['revenue'] = revenue
context['revenue_no_shipping'] = revenue_no_shipping
context['filtromes'] = self.request.GET.get('filtromes', '0')
context['orderby'] = self.request.GET.get('orderby', 'created')
context['category'] = "catalogo"
return context
但在模板中,我得到:
对于收入:{'revenue': Decimal('42')} #is 42.00
对于income_no_shipping:<QuerySet [<Order: 58>]> #Should be 25.00
模型.py:
class Order(models.Model):
ORDER_STATUS = (
('recibido_pagado', 'Recibido y pagado'),
('recibido_no_pagado', 'Recibido pero no pagado'),
('en_proceso', 'En proceso'),
('en_camino', 'En camino'),
('entregado', 'Entregado'),
('cancelado', 'Cancelado por no pagar' )
)
token = models.CharField(max_length=100, blank=True, null=True)
first_name = models.CharField(max_length=50, blank=True, null=True)
last_name = models.CharField(max_length=50, blank=True, null=True)
phone_number = models.CharField(max_length=30, blank=True)
total = models.DecimalField(max_digits=10, decimal_places=2)
stickers_price = models.DecimalField(max_digits=10, decimal_places=2)
discount = models.DecimalField(max_digits=10, decimal_places=2, default=Decimal('0.00'))
shipping_cost = models.DecimalField(max_digits=10, decimal_places=2)
email = models.EmailField(max_length=250, blank = True, verbose_name= 'Correo electrónico')
last_four = models.CharField(max_length=100, blank=True, null=True)
created = models.DateTimeField(auto_now_add=True)
shipping_address = models.CharField(max_length=100, blank=True, null=True)
shipping_address1 = models.CharField(max_length=100, blank=True, null=True)
reference = models.CharField(max_length=100, blank=True, null=True)
shipping_department = models.CharField(max_length=100, blank=True, null=True)
shipping_province = models.CharField(max_length=100, blank=True, null=True)
shipping_district = models.CharField(max_length=100, blank=True, null=True)
reason = models.CharField(max_length=400, blank=True, null=True, default='')
status = models.CharField(max_length=20, choices=ORDER_STATUS, default='recibido_pagado')
comments = models.CharField(max_length=400, blank=True, null=True, default='')
cupon = models.ForeignKey('marketing.Cupons', blank=True, null=True, default=None, on_delete=models.SET_NULL)
class Meta:
db_table = 'Order'
ordering = ['-created']
def __str__(self):
return str(self.id)
def igv(self):
igv = int(self.total) * 18/100
return igv
def shipping_date(self):
shipping_date = self.created + datetime.timedelta(days=10)
return shipping_date
def deposit_payment_date(self):
deposit_payment_date = self.created + datetime.timedelta(days=2)
return deposit_payment_date
更新 1:
模板中的 HTML
<h1>Ordenes recibidas y pagadas:</h1>
<p> {{ revenue }}</p>
<h1>Ordenes recibidas y pgadas (no shipping)</h1>
<p> {{ revenue_no_shipping }}</p>
更新了 get_context_data 方法:
def get_context_data(self, **kwargs):
context = super(OrdersListView, self).get_context_data(**kwargs)
qs = kwargs.pop('object_list', self.object_list)
order = self.request.GET.get('orderby', 'created')
context = {}
revenue = qs.aggregate(revenue=Sum('total'))
revenue_no_shipping = qs.aggregate(revenue_no_shipping=Sum(F('total') + F('shipping_cost')))
context['revenue'] = revenue
context['revenue_no_shipping'] = revenue_no_shipping
context['filtromes'] = self.request.GET.get('filtromes', '0')
context['orderby'] = self.request.GET.get('orderby', 'created')
context['category'] = "catalogo"
return context
最终答案:
根据jmunsch
我得到正确答案的答案,只需添加:
revenue = float(revenue['revenue']) #necessary to properly render in template / not as Decimal
revenue_no_shipping = float(revenue_no_shipping['revenue_no_shipping']) #necessary to properly render in template / not as Decimal
在模板中正确渲染。
def get_context_data(self, **kwargs):
context = super(OrdersListView, self).get_context_data(**kwargs)
qs = kwargs.pop('object_list', self.object_list)
order = self.request.GET.get('orderby', 'created')
context = {}
revenue = qs.aggregate(revenue=Sum('total'))
revenue_no_shipping = qs.aggregate(revenue_no_shipping=Sum(F('total') - F('shipping_cost')))
revenue = float(revenue['revenue']) #necessary to properly render in template / not as Decimal
revenue_no_shipping = float(revenue_no_shipping['revenue_no_shipping']) #necessary to properly render in template / not as Decimal
context['revenue'] = revenue
context['revenue_no_shipping'] = revenue_no_shipping
context['filtromes'] = self.request.GET.get('filtromes', '0')
context['orderby'] = self.request.GET.get('orderby', 'created')
context['category'] = "catalogo"
return context
解决方案
像这样的东西可能适用于如何使用 django 对两列求和:
qs.aggregate(revenue_no_shipping=Sum(F('total') - F('shipping_cost')))
推荐阅读
- javascript - Sweetalert 不会显示,但会更新
- java - 种类
HashMap 使用比较器且不使用 TreeMap - http - 最小的 HTTP POST
- tensorflow - tf.keras.losses.CategoricalCrossentropy 给出的值与普通实现不同
- excel - 我可以告诉 Excel 保持自动二次模型 y>= 0,而不尝试运行手动模型吗?
- javascript - 如何在单击 btn 时自动播放下一首歌曲
- java - 从 SocketChannel 到 SocketChannel 的零拷贝
- nginx - 使用 nginx pod 作为反向代理与 nginx 入口之间的区别
- firebase - 如何使用firebase实时数据库按日期时间过滤记录
- python - 由 docker 启动时无法访问设备/ip,但从同一容器内的 shell