Django ORM cannot resolve keyword for related field for aggregate when model used by more than one application

StackOverflow https://stackoverflow.com/questions/19760876

문제

In Django 1.5 I have 3 apps: common, app1, app2 in which I have the following (simplified) models:

# 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")

app1 is listed before app2 in INSTALLED_APPS.

When I try to create the following queryset:

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

I get back:

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

Where the list of choices provided does not include 'app1_places' but does contain 'app2_tags'. However if I try to reference app1_places on a model instance I don't get an error; it works fine:

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

Annotate with app2_tags works too:

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

Is this a bug in django or is there something I am doing wrong configuring these fields.

edit: here is the stack trace:

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

Note: some app1 models are using the GeoDjango GeoManager (including places) but there are also models in app1 which don't use the geomanager and have foreign keys that also do not work with annotate.

도움이 되었습니까?

해결책

It turns out the issue was with a proxy model that was on app1 and not app2. The proxy model had a custom manager:

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

    class Meta:
        proxy = True

App2 is not using a corresponding proxy model for ApiUser. When django first loads all the models to determine the model domain and calculate backwards references the overridden manager in the proxy model short-circuited the loading of app1.models, leaving all the backwards references for that module uninitialised.

Removing the custom manager definition resolved the issue.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top