Mysql 使用值为:groupby:django的聚合

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)

我想返回一个产品名,使用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 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:如果您使用样本数据编辑您的问题,以及您希望结果是什么样子,可能会有所帮助。现在看起来你问了一些相互矛盾的问题(比如聚合和注释)。谢谢,它应该很好用,谢谢你给我时间,你一直在帮助我