如何在使用Django泛型关系时进行正确的反向查询



我已经实现了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.

根据这个答案,如何遍历Django中的GenericForeignKey?,定义GenericRelation可能会解决我的问题。但话说回来,我没有定义GenericRelation,因为添加一个将根据默认行为级联所有关系

与ForeignKey不同,GenericForeignKey不接受on_delete参数来自定义此行为;如果需要,您可以通过不使用GenericRelation来避免级联删除,并且可以通过pre_delete信号提供替代行为。

如果您不想在BilledVehicle模块中创建GenericRelation对象,django将无法使用值将其直接链接到Bill

您可以通过使用字典来存储BillPayment查询集中唯一的CessPoint标题及其total(自己做注释(来解决此问题,如下所示。

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

最新更新