我有一个用通用外键定义的模型,如下所示:
class Status(models.Model):
request_type = models.ForeignKey(ContentType)
request_id = models.PositiveIntegerField()
request = GenericForeignKey('request_type', 'request_id')
当我使用普通查询集获取关系时,它可以正常工作。
statuses = Status.objects.all()
for status in statuses:
print status.request.name
这会正常打印所有名称。
但是我使用的是Django eztables,它依赖于抓取像
这样的值statuses = Status.objects.all().values('request__name')
然而,当我尝试这个时,我得到:
FieldError: Cannot resolve keyword 'request' into field. Choices are: request_id, request_type, request_type_id
有没有办法在Django中实现这个目标?
答案 0 :(得分:2)
我明白了。
您必须使用以下名称定义对象:
class Status(BaseRequestStatus):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
... more data
然后,在您要过滤的对象中,您必须创建反向泛型关系:
class Request(models.Model):
statuses = GenericRelation(Status, related_query_name='request')
... other data
然后最后你可以做一些有趣的事情,比如
statuses = Status.objects.all().values('request__name')
或
Status.objects.filter(request__name__contains="stack overflow")
答案 1 :(得分:0)
根据the contenttypes framework的文档:
由于
GenericForeignKey
的实施方式,您无法通过数据库API直接将这些字段用于过滤器(例如filter()
和exclude()
)。
由于values()
是此API的一部分,并且在Aggregations and other QuerySet clauses的文档中仅列出filter()
/ exclude()
下面的两个部分,我的猜测就是为什么方法失败。
我建议改为:
status_list = Status.objects.all()
statuses = [{'request__name': status.request.name} for status in status_list]
当然,列表理解中的字典键可以是你想要的任何东西。我把它们留给了'request__name'
,因为如果你的方法运作正常,你就会得到它。