请注意:类似的问题对我没有帮助,因为它们在同一班级中使用了类别-外键。
我有一个带有发票,职位,产品和类别模型的简单发票应用。产品绑定到类别。 我的目标是创建一个查询集
分组查询的预期结果应如下所示:
您能帮我创建一个查询,对经过过滤的日期范围内的类别进行分组和汇总吗?
我唯一能创建的解决方案是特定日期范围的过滤器:
queryset = Position.objects.filter(invoice__date_of_purchase__range=['2019-01-01', '2019-12-31'])
models.py(我已经简化了):
from django.db import models
from django.urls import reverse
class Category(models.Model):
name = models.CharField(max_length=30, unique=True)
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=120)
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='products')
def __str__(self):
return self.name
class Invoice(models.Model):
invoice_code = models.CharField(max_length=15)
date_of_purchase = models.DateField()
customer_name = models.CharField(max_length=100)
def __str__(self):
return self.invoice_code
class Position(models.Model):
invoice = models.ForeignKey(Invoice, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.DecimalField(decimal_places=2, max_digits=6)
price = models.DecimalField(decimal_places=2, max_digits=8)
total = models.DecimalField(
decimal_places=2, max_digits=8, blank=True, null=True) # is calculated in view
def __str__(self):
return self.product.name
答案 0 :(得分:2)
以下过滤器将返回在日期范围内具有发票的所有类别,还将过滤注释以仅对这些发票的那些位置求和
categories = Category.objects.filter(
products__position__invoice__date_of_purchase__range=['2019-11-17', '2019-12-31']
).annotate(
sum=Sum('products__position__total')
)
每个类别现在都将使用属性“ sum”进行注释
for category in categories:
print(category, category.sum)
答案 1 :(得分:0)
我将根据我的经验提出一个调整。
将位置放入多个字段中的发票模型中。这样可以更便宜地过滤发票的日期范围。根据您的用例,它也可能有助于添加“已发送” bol字段。
在您的视图中或在utils.py文件中。循环遍历查询集的“ Position's”字段,其中类别作为条件以按类别分开,并且+ = Position.total字段分配给您的等待变量。