Mysql 使用值为:groupby:django的聚合
我想返回一个产品名,使用distinct,并且我还使用了聚合来进行一些计算 这是我的模特Mysql 使用值为:groupby:django的聚合,mysql,django,Mysql,Django,我想返回一个产品名,使用distinct,并且我还使用了聚合来进行一些计算 这是我的模特 class CustomerInvoice(models.Model): customer = models.CharField(max_length=50) items = models.ManyToManyField(Product,through='ProductSelecte') date = models.DateTimeField(auto_now_add=True)
class CustomerInvoice(models.Model):
customer = models.CharField(max_length=50)
items = models.ManyToManyField(Product,through='ProductSelecte')
date = models.DateTimeField(auto_now_add=True)
class ProductSelecte(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
products= models.ForeignKey(CustomerInvoice,on_delete=models.CASCADE,related_name='product')
qnt= models.IntegerField(default=1)
price = models.IntegerField()
cash = models.IntegerField()
我想做一个表格来跟踪客户的活动
这是我的问题
context['clients'] = ProductSelecte.objects.filter(
products__customer=self.object.name).values('product').annotate(quantity=Sum(F('qnt'))).order_by('product')
直到在这里工作很好,但我也需要使用这个总价格
.aggregate(
total_price=Sum(F('price')))
它引起了这个错误
“dict”对象没有属性“order\u by”
谢谢你的帮助
更新
例如,在6月4日约翰的第一张发票上,约翰买了两支钢笔,价格是20美元,3本书的价格是30美元,这张发票的总价是50美元,7月5日的第二张发票上,他买了一支钢笔,价格是10美元,2本书的价格是20美元,总价是30美元,我需要这样的结果
client : john , activities : 3 pen(total pens he bought till now),price pens : 30 (total pens price he bought till now) , 3 book(total books he bought till now) ; price:30(total books price he bought till now) ,2 copybook ;price:20
and then total price of both invoice : 30+50 = 80
您应该对每个产品的每个客户机进行注释,然后在Django/Python级别执行一些“分组”:
from django.db.models import F, Sum
from itertools import groupby
from operator import itemgetter
qs = ProductSelecte.objects.values(
customer=F('products__customer')
product=F('product')
).annotate(quantity=Sum('qnt')).order_by('customer', 'product')
data = {
k: list(vs)
for k, vs in groupby(qs, itemgetter('customer'))
}
这里的数据
是一个字典,它将客户的名称
映射到包含产品
id、客户名称和数量的字典列表
如果将其传递给模板,例如,可以使用以下方法渲染:
<ul>
{% for c, vs in data.items %}
<li>{{ c }}</li>
<ul>
{% for v in vs %}
<li>{{ v.product }}: {{ v.quantity }}</li>
{% endfor %}
</ul>
{% endfor %}
</ul>
{c的%vs在data.items%}
- {{c}}
{vs%中的v为%v}
- {{v.product}}:{{v.quantity}
{%endfor%}
{%endfor%}
编辑:根据更新后的请求,您应该进行注释和聚合请求:
class ProfileClientDetailView(LoginRequiredMixin,DetailView):
# …
def get_object(self):
return get_object_or_404(Client,pk=self.kwargs['pk'])
def get_context_data(self,*args,**kwargs):
data = super().get_context_data(*args,**kwargs)
data['products'] = ProductSelecte.objects.filter(
products__customer=self.object.name
).values('product').annotate(
quantity=Sum('qnt'),
total_price=Sum('price')
).order_by('product')
data['total'] = ProductSelecte.objects.filter(
products__customer=self.object.name
).aggregate(
quantity=Sum('qnt'),
total_price=Sum('price')
)
return data
class ProfileClientDetailView(LoginRequiredMixin,DetailView):
# …
def get_对象(自身):
返回get_object_或_404(客户端,pk=self.kwargs['pk'])
def获取上下文数据(self、*args、**kwargs):
data=super()。获取上下文数据(*args,**kwargs)
数据['products']=ProductSelecte.objects.filter(
产品\客户=self.object.name
).值(“产品”)。注释(
数量=总和(“qnt”),
总价=总和(“价格”)
).订购人(“产品”)
数据['total']=ProductSelecte.objects.filter(
产品\客户=self.object.name
).合计(
数量=总和(“qnt”),
总价=总和(“价格”)
)
返回数据
然后可以将其渲染为:
<ul>
{% for pr in products %}
<li>{{ pr.product }}: {{ pr.total_price }} ({{ pr.quantity }} items)</li>
</ul>
TOTAL: {{ total.total_price }} ({{ total.quantity }} items)
{产品%中的pr为%0}
- {{pr.product}}:{{pr.total_price}}({pr.quantity}}项)
总计:{{TOTAL.TOTAL_price}}({{TOTAL.quantity}}项)
为什么要聚合?如果你合计,那么一个.order\u by
就没有多大意义,因为这样你就得到了所有价格的总和,所以产品就“消失”了。我需要知道一个客户的总价格,但如果不使用order\u by,我们就无法区分值,正如我在问题中提到的,我需要知道产品名称和该产品的总数量,然后为特定客户的所有产品的总价格!然后您需要.annotate(..)
,因为这将使每个值的聚合。如果每个产品的每个客户机都需要它,那么不能使用QuerySet
,那么需要在Python逻辑中进行一些后处理。是的,我需要它来为每个客户机制作,怎么做?你是说查询中的for循环吗?@art_cs:将它添加到上下文中,因此数据['data']={…}
@art_cs:如果你需要总数,然后您可以.aggregate(..)
,但是不需要.order\u by(..)
。然后,它将返回一本包含总量的字典(如果你对价格进行汇总,则返回价格)…@art_cs:但如果你进行了总量计算,那么它显然不会返回产品名称,因为你会汇总所有记录,而不考虑产品。在这样的查询中,产品名称有什么意义?@art_cs:如果您使用样本数据编辑您的问题,以及您希望结果是什么样子,可能会有所帮助。现在看起来你问了一些相互矛盾的问题(比如聚合和注释)。谢谢,它应该很好用,谢谢你给我时间,你一直在帮助我