Breaks when trying to refer to a model defined later in models.py

Bug #613817 reported by Daniel Abel
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
django-sortedm2m
New
Undecided
Unassigned

Bug Description

in create_intermediary_model(), the modelclass that the given SortedManyToManyField field will refer to is looked up, if it is given as a string. This lookup fails if that modelclass is defined later in models.py, since then it won't be known by django, and thus models.get_model() will return None, resulting in an AssertionError:

AssertionError: ForeignKey(None) is invalid. First parameter to ForeignKey must be either a model, a model name, or the string 'self'

Is there any chance this can be fixed?

(A workaround can be to structure one's models.py so that models don't reference modelclasses defined later on, but that might be hard / impossible)

Revision history for this message
Daniel Abel (abeld) wrote :

Oh yes, and if this can't be fixed, then it should be documented.

Revision history for this message
Daniel Abel (abeld) wrote :

Note that even if the models are ordered so that only actual classes (and not classnames) are pass as arguments to SortedManyToManyField, this problem still comes up when trying to use south: south stores the argument used as a string, and the AssertionError is triggered when the migration is applied.

Revision history for this message
Daniel Abel (abeld) wrote :

An idea: isn't this supposed to be handled by using add_lazy_relation()? (I'll try to look whether that can be used to solve this issue)

Revision history for this message
Gregor Müllegger (gregor-muellegger) wrote :

Hi Daniel,

thanks for your report. Unfortunatelly I cannot reproduce this problem - do you agree that the following example should reveal the problem:

class Shelf(models.Model):
    books = SortedManyToManyField('Book')

class Book(models.Model):
   ...

This works for me and I use it this way in the latest testsuite I pushed to the repository.

Revision history for this message
Daniel Abel (abeld) wrote :
Download full text (4.3 KiB)

Yes, and in fact this appears to exhibit the problem. Using version 0.2.3 of sortedm2m with django 1.2, and the following models.py:
--------------------------------------
from django.db import models
from sortedm2m.fields import SortedManyToManyField

# Create your models here.

class Shelf(models.Model):
    books = SortedManyToManyField('Book')

class Book(models.Model):
    title = models.CharField(50)
--------------------------------------
When running syncdb, I get:
(env)abeld@csik:0:/mnt/data/abeld/WORK/maven/FirmNetOnline/sortedm2m_bug/sortedm2m_debug$ python manage.py syncdb
Traceback (most recent call last):
  File "manage.py", line 11, in <module>
    execute_manager(settings)
  File "/mnt/data/abeld/WORK/maven/FirmNetOnline/sortedm2m_bug/env/lib/python2.6/site-packages/django/core/management/__init__.py", line 438, in execute_manager
    utility.execute()
  File "/mnt/data/abeld/WORK/maven/FirmNetOnline/sortedm2m_bug/env/lib/python2.6/site-packages/django/core/management/__init__.py", line 379, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/mnt/data/abeld/WORK/maven/FirmNetOnline/sortedm2m_bug/env/lib/python2.6/site-packages/django/core/management/base.py", line 191, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/mnt/data/abeld/WORK/maven/FirmNetOnline/sortedm2m_bug/env/lib/python2.6/site-packages/django/core/management/base.py", line 217, in execute
    self.validate()
  File "/mnt/data/abeld/WORK/maven/FirmNetOnline/sortedm2m_bug/env/lib/python2.6/site-packages/django/core/management/base.py", line 245, in validate
    num_errors = get_validation_errors(s, app)
  File "/mnt/data/abeld/WORK/maven/FirmNetOnline/sortedm2m_bug/env/lib/python2.6/site-packages/django/core/management/validation.py", line 28, in get_validation_errors
    for (app_name, error) in get_app_errors().items():
  File "/mnt/data/abeld/WORK/maven/FirmNetOnline/sortedm2m_bug/env/lib/python2.6/site-packages/django/db/models/loading.py", line 146, in get_app_errors
    self._populate()
  File "/mnt/data/abeld/WORK/maven/FirmNetOnline/sortedm2m_bug/env/lib/python2.6/site-packages/django/db/models/loading.py", line 61, in _populate
    self.load_app(app_name, True)
  File "/mnt/data/abeld/WORK/maven/FirmNetOnline/sortedm2m_bug/env/lib/python2.6/site-packages/django/db/models/loading.py", line 78, in load_app
    models = import_module('.models', app_name)
  File "/mnt/data/abeld/WORK/maven/FirmNetOnline/sortedm2m_bug/env/lib/python2.6/site-packages/django/utils/importlib.py", line 35, in import_module
    __import__(name)
  File "/mnt/data/abeld/WORK/maven/FirmNetOnline/sortedm2m_bug/sortedm2m_debug/myapp/models.py", line 6, in <module>
    class Shelf(models.Model):
  File "/mnt/data/abeld/WORK/maven/FirmNetOnline/sortedm2m_bug/env/lib/python2.6/site-packages/django/db/models/base.py", line 93, in __new__
    new_class.add_to_class(obj_name, obj)
  File "/mnt/data/abeld/WORK/maven/FirmNetOnline/sortedm2m_bug/env/lib/python2.6/site-packages/django/db/models/base.py", line 213, in add_to_class
    value.contribute_to_class(cls, name)
  File "/mnt/data/abeld/WORK/maven/FirmNetOnline/sortedm2m_bug/env/lib/python2....

Read more...

Revision history for this message
Daniel Abel (abeld) wrote :
Revision history for this message
Gregor Müllegger (gregor-muellegger) wrote :

I committed a fix for your report. But it's not ready yet for a release since 'self' reference doesn't work yet. I have to work on it a bit more. I hope to get it fixed to the end of the week.

Revision history for this message
Daniel Abel (abeld) wrote :

Thanks, that fix works for me. Thanks for the quick fix!

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.