#23348 closed Uncategorized (invalid)

Changes in Django 1.7 break nested Applications

Reported by: glassresistor Owned by: nobody
Component: Core (Serialization) Version: master
Severity: Release blocker Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


Currently applications like django-oauth2-provider which include nested applications for organizational reasons now break in 1.7.

Causing errors like
DeserializationError: Problem installing fixture '/home/mike/code/django-oauth2-provider/provider/oauth2/fixtures/test_oauth2.json': Invalid model identifier: 'oauth2.client'

The issue is that dev now names this provider_client instead of oauth2_client within the database itself.
I've gone through and manually set the db_table to what it would be in 1.6 and am still getting the serialization error on the fixture because oauth2 doesn't exist as an application.

Its not clear if the solution is to make it act like 1.6 in these cases or to better document the compatibility difference.

Change History (2)

comment:1 Changed 14 months ago by glassresistor

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

Heres a link to an example codebase https://github.com/glassresistor/django-oauth2-provider/tree/7ab7a17531e5d9e7e0c32f32723ea62601c9d80a
in an virtualenv
pip install -r requirements.txt
pip install -e git+https://github.com/django/django.git#egg=django
python manage.py test

Last edited 14 months ago by glassresistor (previous) (diff)

comment:2 Changed 14 months ago by aaugustin

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

The release notes say:

You should make sure that (...) models aren’t imported as a side-effect of loading their application.

You're doing the exact opposite by explicitly importing your models module, and many others, in your apps module. This is bad. apps shouldn't import anything (except maybe inside an AppConfig.ready) method.

When Django encounters your models, it looks for the innermost application containing them, finds provider, doesn't find provider.oauth2 because it isn't loaded yet (remember, we're in the process of importing its apps module), so it uses provider.

When you define a model outside of models.py, in Django < 1.7, you had to provide an app_label:

Unfortunately, it was very easy to miss that line and forget to set app_label. In that case, Django < 1.7 silently uses a wrong label — one that doesn't match any installed application — rather than at least failing loudly.

That bug was fixed in Django 1.7 by making the app detection code smarter. It accounts specifically for nested apps, that is, if an app contains an another app, models will be automatically associated with the innermost currently loaded apps.

That requires loading all apps before starting to load models.

I know that attempting to control import order in Python is a painful exercise, but that what we're stuck with, at least until the deprecation period completes and we can shed some backwards-compatibility code. So please don't import models in apps and you'll be all right.

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