从Django中的通用外键获取值

时间:2015-11-04 22:45:17

标签: python django django-models

我有一个用通用外键定义的模型,如下所示:

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中实现这个目标?

2 个答案:

答案 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',因为如果你的方法运作正常,你就会得到它。