1

在 Django 1.5 中,我有 3 个应用程序:common、app1、app2,其中我有以下(简化的)模型:

# common/models.py
class ApiUser(models.Model):
    username = models.CharField(max_length=255)
    channel = models.CharField(max_length=20)

# app1/models.py
class Place(models.Model):
    title = models.CharField(max_length=255)
    created_by = models.ForeignKey('common.ApiUser', null=True, related_name="%(app_label)s_places")

# app2/models.py
class Tag(models.Model):
    name = models.CharField(max_length=255)
    user = models.ForeignKey('common.ApiUser', null=True, related_name="%(app_label)s_tags")

app1app2之前在 中列出INSTALLED_APPS

当我尝试创建以下查询集时:

qs = ApiUser.objects.filter(channel='app1').annotate(Count('app1_places'))

我回来了:

Cannot resolve keyword 'app1_places' into field. Choices are: app2_tags, channel, username

提供的选项列表不包括'app1_places'但确实包含'app2_tags'. 但是,如果我尝试app1_places在模型实例上引用,我不会收到错误消息;它工作正常:

>>> u = ApiUser.objects.get(pk=23)
>>> u.app1_places.all()
[]

app2_tags也用作品注释:

qs = ApiUser.objects.filter(channel='app2').annotate(Count('app2_tags'))

这是 django 中的错误还是我在配置这些字段时做错了什么。

编辑:这是堆栈跟踪:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/vagrant/.virtualenvs/thorium/lib/python2.6/site-packages/django/db/models/query.py", line 795, in annotate
    is_summary=False)
  File "/home/vagrant/.virtualenvs/thorium/lib/python2.6/site-packages/django/db/models/sql/query.py", line 1019, in add_aggregate
field_list, opts, self.get_initial_alias(), False)
  File "/home/vagrant/.virtualenvs/thorium/lib/python2.6/site-packages/django/db/models/sql/query.py", line 1337, in setup_joins
  "Choices are: %s" % (name, ", ".join(names)))
FieldError: Cannot resolve keyword 'app1_places' into field. Choices are: app2_tags, channel, username

注意:一些 app1 模型正在使用 GeoDjango GeoManager(包括位置),但 app1 中也有一些模型不使用 geomanager 并且具有也不适用于注释的外键。

4

1 回答 1

1

事实证明,问题出在 app1 而不是 app2 上的代理模型上。代理模型有一个自定义管理器:

# app1/models.py
class App1User(common_models.ApiUser):
    objects = common_models.ApiUser.objects.filter(channel='app1')

    class Meta:
        proxy = True

App2 没有为 ApiUser 使用相应的代理模型。当 django 第一次加载所有模型以确定模型域并计算反向引用时,代理模型中的重写管理器使 app1.models 的加载短路,使该模块的所有反向引用未初始化。

删除自定义管理器定义解决了该问题。

于 2013-11-04T04:33:53.917 回答