Opened 10 years ago

Closed 10 years ago

#23348 closed Uncategorized (invalid)

Changes in Django 1.7 break nested Applications

Reported by: None Owned by: nobody
Component: Core (Serialization) Version: dev
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

Description

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 by None, 10 years ago

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 10 years ago by None (previous) (diff)

comment:2 by Aymeric Augustin, 10 years ago

Resolution: invalid
Status: newclosed

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:
https://docs.djangoproject.com/en/1.6/ref/models/options/#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