使用 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
我已经实现了 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.
根据这个答案,
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