我正在使用 Django v1.9.4 和 PostgreSQL 9.2.14。使用以下型号:
from django.db import models
from django.contrib.contenttypes.fields import GenericRelation, GenericForeignKey
from django.contrib.contenttypes.models import ContentType
class Foo(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
bar = GenericForeignKey('content_type', 'object_id')
class Bar(models.Model):
foos = GenericRelation(Foo, related_query_name='bars')
class Meta:
abstract = True
class BarX(Bar):
name = models.CharField(max_length=10, default='bar x')
class BarY(Bar):
name = models.CharField(max_length=10, default='bar y')
创建一些实例来演示我的问题:
>>> bar_x = BarX.objects.create()
>>> bar_y = BarY.objects.create()
>>> foo1 = Foo.objects.create(bar=bar_x)
>>> foo2 = Foo.objects.create(bar=bar_y)
>>> foo1.bar.name
u'bar x'
>>> foo2.bar.name
u'bar y'
我无法在 django 中遍历 GFK,尝试过滤会引发异常,并提示添加GenericRelation
. 但是通过相关查询名称使用通用关系bars
并不能可靠地工作。例如:
>>> [foo.bar.name for foo in Foo.objects.all()]
[u'bar x', u'bar y'] # in a pure python loop, it's working
>>> Foo.objects.filter(bar__name='bar x')
FieldError: Field 'bar' does not generate an automatic reverse relation and therefore cannot be used for reverse querying. If it is a GenericForeignKey, consider adding a GenericRelation.
>>> Foo.objects.values_list('bars__name', flat=1)
[None, u'bar y'] # but why None is returned in here?
>>> Foo.objects.filter(bars__name='bar x')
[] # why no result here?
>>> Foo.objects.filter(bars__name='bar y')
[<Foo: Foo object>] # but this one works?
我究竟做错了什么?
给未来读者的注意事项: 模板在 Django 1.9related_query_name
上GenericRelation
无法正常工作。
在合并 #25354的修复后,在Django 1.10 中添加了related_query_name 现在支持使用 '%(app_label)s' 和 '%(class)s' 字符串的应用程序标签和类插值。
如果您使用的是 Django 1.10,则可以继续将其GenericRelation
放在抽象基类和模板上,related_query_name='%(app_label)s_%(class)s'
以确保子类之间的唯一性。