Code

Opened 6 years ago

Closed 6 years ago

Last modified 3 years ago

#8615 closed (invalid)

Changeset 8605 breaks model loading under unknown circumstances

Reported by: aeby Owned by: nobody
Component: contrib.admin Version: master
Severity: Keywords: introspect models admin validation
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

[8605] seems to be a backward incompatible change. Without the line models.get_apps() the models can be loaded without any problem.
If get_apps is called I receive the following trace:

Validating models...
Traceback (most recent call last):
  File "/usr/local/bin/django-admin.py", line 5, in <module>
    management.execute_from_command_line()
  File "/PATH/TO/DJANGO/django/core/management/__init__.py", line 325, in execute_from_command_line
    utility.execute()
  File "/PATH/TO/DJANGO/django/core/management/__init__.py", line 295, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/PATH/TO/DJANGO/django/core/management/base.py", line 77, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/PATH/TO/DJANGO/django/core/management/base.py", line 96, in execute
    output = self.handle(*args, **options)
  File "/PATH/TO/DJANGO/django/core/management/commands/runserver.py", line 77, in handle
    inner_run()
  File "/PATH/TO/DJANGO/django/core/management/commands/runserver.py", line 47, in inner_run
    self.validate(display_num_errors=True)
  File "/PATH/TO/DJANGO/django/core/management/base.py", line 122, in validate
    num_errors = get_validation_errors(s, app)
  File "/usr/lib/python2.5/site-packages/django/core/management/validation.py", line 28, in get_validation_errors
    for (app_name, error) in get_app_errors().items():
  File "/PATH/TO/DJANGO/django/db/models/loading.py", line 128, in get_app_errors
    self._populate()
  File "/PATH/TO/DJANGO/django/db/models/loading.py", line 57, in _populate
    self.load_app(app_name, True)
  File "/PATH/TO/DJANGO/django/db/models/loading.py", line 72, in load_app
    mod = __import__(app_name, {}, {}, ['models'])
  File "/home/aeby/workspace/atizo/src/atizo/platform/models/__init__.py", line 14, in <module>
    from atizo.platform.models.country import Country
  File "/home/aeby/workspace/atizo/src/atizo/platform/models/country.py", line 16, in <module>
    from atizo.platform.models.multilang_text import MultilangText
  File "/home/aeby/workspace/atizo/src/atizo/platform/models/multilang_text.py", line 57, in <module>
    admin.site.register(MultilangText, MultilangTextAdmin)
  File "/PATH/TO/DJANGO/django/contrib/admin/sites.py", line 91, in register
    validate(admin_class, model)
  File "/PATH/TO/DJANGO/django/contrib/admin/validation.py", line 22, in validate
    models.get_apps()
  File "/PATH/TO/DJANGO/django/db/models/loading.py", line 97, in get_apps
    self._populate()
  File "/PATH/TO/DJANGO/django/db/models/loading.py", line 57, in _populate
    self.load_app(app_name, True)
  File "/PATH/TO/DJANGO/django/db/models/loading.py", line 72, in load_app
    mod = __import__(app_name, {}, {}, ['models'])
  File "/home/aeby/workspace/atizo/src/atizo/../atizo/channels/models/__init__.py", line 15, in <module>
    from channel import Channel
  File "/home/aeby/workspace/atizo/src/atizo/../atizo/channels/models/channel.py", line 40, in <module>
    admin.site.register(Channel, ChannelAdmin)
  File "/PATH/TO/DJANGO/django/contrib/admin/sites.py", line 91, in register
    validate(admin_class, model)
  File "/PATH/TO/DJANGO/django/contrib/admin/validation.py", line 22, in validate
    models.get_apps()
  File "/PATH/TO/DJANGO/django/db/models/loading.py", line 97, in get_apps
    self._populate()
  File "/PATH/TO/DJANGO/django/db/models/loading.py", line 57, in _populate
    self.load_app(app_name, True)
  File "/PATH/TO/DJANGO/django/db/models/loading.py", line 72, in load_app
    mod = __import__(app_name, {}, {}, ['models'])
  File "/home/aeby/workspace/atizo/src/atizo/../atizo/projects/models/__init__.py", line 15, in <module>
    from idea import Idea
  File "/home/aeby/workspace/atizo/src/atizo/projects/models/idea.py", line 16, in <module>
    from atizo.platform.models.language import Language
  File "/home/aeby/workspace/atizo/src/atizo/../atizo/platform/models/language.py", line 37, in <module>
    admin.site.register(Language, LanguageAdmin)
  File "/PATH/TO/DJANGO/django/contrib/admin/sites.py", line 91, in register
    validate(admin_class, model)
  File "/PATH/TO/DJANGO/django/contrib/admin/validation.py", line 22, in validate
    models.get_apps()
  File "/PATH/TO/DJANGO/django/db/models/loading.py", line 97, in get_apps
    self._populate()
  File "/PATH/TO/DJANGO/django/db/models/loading.py", line 57, in _populate
    self.load_app(app_name, True)
  File "/PATH/TO/DJANGO/django/db/models/loading.py", line 72, in load_app
    mod = __import__(app_name, {}, {}, ['models'])
  File "/home/aeby/workspace/atizo/src/atizo/personal/models/__init__.py", line 19, in <module>
    from userprofile import UserProfileUrl
  File "/home/aeby/workspace/atizo/src/atizo/personal/models/userprofile.py", line 21, in <module>
    from atizo.platform.models.country import Country
ImportError: cannot import name Country

It seems to be quite hard to locate the problem :(

Attachments (0)

Change History (4)

comment:1 Changed 6 years ago by mtredinnick

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Summary changed from Changeset 8605 breaks model loading under unknow circumstances to Changeset 8605 breaks model loading under unknown circumstances

From the traceback, it looks like you might be calling admin.site.register() from inside the same file as you create the models. For example, it looks like atizo.platform.models.multilang_text creates the MultiLangText model and also registers it with the admin.

If that is correct, then don't do that. The admin registration doesn't work in a number of subtle cases in that setup, since we reimport the models from time to time.

This traceback looks like it exposing an existing problem in your code in a more visible way than previously. Basically, you have a circular import dependency going on because you're importing models by name explicitly. So the platform.models.country module is being imported and all the consequences of that (including the admin.sites.register() call) are leading to nested imports, culminating in an attempt to import Country from platform.models.country, which is already being imported right at the top (and isn't fully imported yet). The solution here is (a) don't call register()` in the models file, as already notes and (b) consider not importing things directly from the module namespace. So, rather than

from platform.models.country import Country

you can write

from platform.models import country

# Then refer to it as country.Country

This is only strictly necessary when you have circular importing going on and that's why it's being triggered here (because the admin app retrieval for registering is triggering all the other imports). It's impossible to work around having to periodically force all the model files to be imported (there are lots of other bugs that we have had to work around and get_apps() is pretty well debugged as a result). We can't even construct a better error than the one Python gives you with the concluding line and the traceback.

Please confirm if you do have the admin.sites.register() call in the models file. If so, we can close this because it isn't a Django bug.

comment:2 Changed 6 years ago by aeby

Thanks for this explanation. Yes, I have the admin.sites.register() call inside in the models file. So you can probably close this bug. But where should I call admin.sites.register() if not in the models file?

comment:3 Changed 6 years ago by kmtracey

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

The recommended places for admin.site.register() calls is in an admin.py file in your app directory. Then admin.autodiscover() in urls.py will find and load the admin.py files for all the apps in INSTALLED_APPS, so your registration calls will be executed. See the admin doc: http://www.djangoproject.com/documentation/admin/

comment:4 Changed 3 years ago by jacob

  • milestone 1.0 deleted

Milestone 1.0 deleted

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.