Django:我可以将objects.filter()用于通用外键吗?



symbol.py

class Symbol(BaseModel):
    name = models.CharField(max_length=30,)
    class Meta:
        abstract = True
class StockSymbol(Symbol):
    market = models.CharField(max_length=10,)
    my_daily_price = GenericRelation(MyDailyPrice)

daily_price.py

class DailyPrice(BaseModel):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')
    class Meta:
        abstract = True
class MyDailyPrice(DailyPrice):
    open = models.DecimalField(
        max_digits=15,
        decimal_places=2,
    )

我想做的是,

symbol = StockSymbol.objects.first()
MyDailyPrice.objects.filter(content_object=symbol)

但它发生了错误:

FieldError: Field 'content_object' does not generate an automatic reverse relation and therefore cannot be used for reverse querying. If it is a GenericForeignKey, consider adding a GenericRelation.

StockSymbol已经有了GenericRelation.怎么了?

还是我必须覆盖ojbect manager

您可以使用

content_typeobject_id进行过滤,而不是content_object

from django.contrib.admin.options import get_content_type_for_model
symbol = StockSymbol.objects.first()
MyDailyPrice.objects.filter(content_type=get_content_type_for_model(symbol), object_id=symbol.pk)

我将@Akash的答案包装在一个要添加到自定义管理器或 QuerySet 的方法中:

def gfks(self, **kwargs):
    filters = {}
    for field, obj in kwargs.items():
        gfk = self.model._meta.get_field(field)
        filters[gfk.ct_field] = ContentType.objects.get_for_model( obj )
        filters[gfk.fk_field] = obj.pk
    return self.filter(**filters)

例如,如果您有一个名为 Comparison 的模型,其中包含两个名为 product1product2 的 GFK,并添加了此方法,则用法如下所示:

comp = Comparison.objects.gfks(product1=foo, product2=bar)

如果 Django 的 contenttypes 应用程序自动提供一些类似的糖会很好,但在此期间我会满足于将其添加到我的 BaseQuerySet 类中。

相关内容

  • 没有找到相关文章

最新更新