Opened 18 years ago

Closed 18 years ago

Last modified 18 years ago

#2232 closed defect (fixed)

ManyRelatedManager is broken in certain conditions (can't get .all() from ManyToManyField)

Reported by: Maniac@… Owned by: Malcolm Tredinnick
Component: Database layer (models, ORM) Version:
Severity: major Keywords:
Cc: Maniac@…, Malcolm Tredinnick Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Looks like changeset 3195 has broken ManyToManyRelations. This simple code shows the problem:

class Article(models.Model):
  authors = models.ManyToManyField(Author)

...

article = Article.objects.all()[0]
article.authors.all() # Exception

The exception is

TypeError: Cannot resolve keyword 'article' into field

Attachments (1)

recursive-import-fix.diff (1.3 KB ) - added by Malcolm Tredinnick 18 years ago.
Partial fix

Download all attachments as: .zip

Change History (11)

comment:1 by anonymous, 18 years ago

Cc: Maniac@… added

comment:2 by Maniac@…, 18 years ago

Summary: ManyRelatedManager is broken (can't get .all() from ManyToManyField)ManyRelatedManager is broken for cross-app relations (can't get .all() from ManyToManyField)

Testing it a bit further shows that this fails only in this two cases:

  1. if a models references another model that is in another app
  2. (this one is strange) In my app I have a User model that is OneToOne-related to auth.contrib.models.User. My User has "roles = models.ManyToMany(Role)" where Role is also in my app. _This_ "roles" relation stopped working as of changeset 3195...

comment:3 by Malcolm Tredinnick, 18 years ago

(In [3202]) Fixed #1796 -- only load a single copy of each model, even when it is
referenced via different import paths. Solves a problem with many-to-many
relations being set up incorrectly. Thanks to Curtis Thompson, Luke Plant and
Simon Willison for some excellent debugging of the problem. Refs #2232 (may
also have fixed that).

comment:4 by Maniac@…, 18 years ago

Resolution: fixed
Status: newclosed

Indeed that fixes it.

comment:5 by Maniac@…, 18 years ago

Cc: Malcolm Tredinnick added
Resolution: fixed
Status: closedreopened
Summary: ManyRelatedManager is broken for cross-app relations (can't get .all() from ManyToManyField)ManyRelatedManager is broken in certain conditions (can't get .all() from ManyToManyField)

Unfortunately this bug still appears even after 'abspath' fix in #1796. This makes me think that this is a separate issue. To summarize:

There are two models (simplified):

from django.contrib.auth.models import User as DjangoUser

class Role(models.Model):
  slug = models.SlugField(unique=True)

class User(models.Model):
  django_user = models.OneToOneField(DjangoUser)
  roles = models.ManyToManyField(Role, blank=True)

When running under dev server from the project's directory as current one by executing "./manage.py runserver" everything works fine.

When running under Apache with mod_python with these settings:

  <Location "/">
    SetHandler python-program
    PythonPath sys.path+['/usr/share/django','/home/maniac/project_parent']
    PythonHandler django.core.handlers.modpython
    SetEnv DJANGO_SETTINGS_MODULE project_name.settings
    PythonDebug On
  </Location>

... then accessing user.roles.all() results in "Cannot resolve keyword 'user' into field"

Apache is running as "www-data" user, dev server as my local user.

I'm absolutely at loss where to start thinkning about it...

comment:6 by Malcolm Tredinnick, 18 years ago

Owner: changed from Adrian Holovaty to Malcolm Tredinnick
Status: reopenednew

by Malcolm Tredinnick, 18 years ago

Attachment: recursive-import-fix.diff added

Partial fix

comment:7 by Malcolm Tredinnick, 18 years ago

The partial fix I just attached fixes part of the problem. I found another way we were creating two instances of a model. Can you try it out and see if it helps in your setup?

comment:8 by Maniac@…, 18 years ago

Yes, looks fixed with the patch. Checked both Apache and dev server this time.

P.S. I look forward to reading your promised explanation in the wiki. This whole issue seems to me a bit fragile, may be there should be some more robust way of registering apps...

comment:9 by Malcolm Tredinnick, 18 years ago

(In [3212]) Fixed another path where imports were creating two instances of a model's
class. Refs #1796, #2232.

comment:10 by Malcolm Tredinnick, 18 years ago

Resolution: fixed
Status: newclosed

As far as I can see, [3212] should have fixed the last problem in this area. Closing now.

Note: See TracTickets for help on using tickets.
Back to Top