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

How to do proper reverse querying when using Django generic relations?

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

根据这个答案,,定义一个 GenericRelation 可能会解决我的问题。但是话又说回来,我没有定义 GenericRelation 因为添加一个会按照默认行为

级联所有关系

Unlike ForeignKey, GenericForeignKey does not accept an on_delete argument to customize this behavior; if desired, you can avoid the cascade-deletion simply by not using GenericRelation, and alternate behavior can be provided via the pre_delete signal.

如果您不想在 BilledVehicle 模块中创建 GenericRelation object,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