Code

Opened 8 years ago

Closed 8 years ago

Last modified 8 years ago

#2232 closed defect (fixed)

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

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

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 mtredinnick 8 years ago.
Partial fix

Download all attachments as: .zip

Change History (11)

comment:1 Changed 8 years ago by anonymous

  • Cc Maniac@… added

comment:2 Changed 8 years ago by Maniac@…

  • Summary changed from ManyRelatedManager is broken (can't get .all() from ManyToManyField) to 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 Changed 8 years ago by mtredinnick

(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 Changed 8 years ago by Maniac@…

  • Resolution set to fixed
  • Status changed from new to closed

Indeed that fixes it.

comment:5 Changed 8 years ago by Maniac@…

  • Cc mtredinnick added
  • Resolution fixed deleted
  • Status changed from closed to reopened
  • Summary changed from ManyRelatedManager is broken for cross-app relations (can't get .all() from ManyToManyField) to 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 Changed 8 years ago by mtredinnick

  • Owner changed from adrian to mtredinnick
  • Status changed from reopened to new

Changed 8 years ago by mtredinnick

Partial fix

comment:7 Changed 8 years ago by mtredinnick

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 Changed 8 years ago by Maniac@…

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 Changed 8 years ago by mtredinnick

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

comment:10 Changed 8 years ago by mtredinnick

  • Resolution set to fixed
  • Status changed from new to closed

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

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.