我已经实现了django通用关系来创建模型之间的关系。我的模特是
class CessPoint(BaseModel):
....
title = models.CharField(max_length=100)
class BilledVehicle(BaseModel):
....
source = models.ForeignKey(CessPoint, on_delete=models.CASCADE)
class Bill(BaseModel):
.....
content_type = models.ForeignKey(
ContentType, on_delete=models.CASCADE, null=True)
object_id = models.UUIDField(null=True)
billed_item = GenericForeignKey()
class BillPayment(BaseModel):
.....
bill = models.ForeignKey(Bill, on_delete=models.CASCADE)
我想为BilledVehicle
付款。这就是我要解决的方法。
BillPayment.objects.filter(bill__content_type=ContentType.objects.get_for_model(BilledVehicle)).values('bill__billed_item__source__title').annotate(total_paid=Sum('amount_paid')).order_by('-total_paid')
我遇到了错误:
Field 'billed_item' does not generate an automatic reverse relation and therefore cannot be used for reverse querying. If it is a GenericForeignKey, consider adding a GenericRelation.
根据此答案How to traverse a GenericForeignKey in Django?,定义 GenericRelation 可能会解决我的问题。但是再说一次,我没有定义 GenericRelation ,因为添加一个将按照默认行为层叠所有关系
与ForeignKey不同,GenericForeignKey不接受on_delete参数来自定义此行为;如果需要,可以通过不使用GenericRelation来避免级联删除,并且可以通过pre_delete信号提供替代行为。
答案 0 :(得分:0)
如果您不想在BilledVehicle
模块中创建GenericRelation对象,django将无法使用值将其直接链接到Bill
。
您可以通过使用字典来存储唯一的CessPoint
标题及其total
(由您自己支付注释),以BillPayment
的查询集来支付,方法如下:
qs = BillPayment.objects.filter(
bill__content_type=ContentType.objects.get_for_model(BilledVehicle))
ds = {}
for billPayment in qs:
title = billPayment.billed_item.source.title
ds[title] = ds.get(title, 0) + billPayment.amount_paid