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:2 by , 10 years ago
Resolution: | → invalid |
---|---|
Status: | new → 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
:
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.
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