#16283 closed Bug (fixed)
manage.py depends on django.contrib.contenttypes et al.
| Reported by: | TheRoSS | Owned by: | nobody |
|---|---|---|---|
| Component: | contrib.auth | Version: | 1.3 |
| Severity: | Normal | Keywords: | |
| Cc: | TheRoSS | Triage Stage: | Accepted |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
I intended to use django.contrib.auth with my own backends, so I included 'django.contrib.auth.middleware.AuthenticationMiddleware' into 'MIDDLEWARE_CLASSES', excluded 'django.contrib.auth' from 'INSTALLED_APPS' and created my own authentication application.
But if I named my authentication application as 'project.auth', django used models from 'django.contrib.auth'.
If I gave it any other name, 'project.auth2' for example, models were mine.
project.settings contains:
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
)
INSTALLED_APPS = (
'project.auth', # DOESN'T WORK!
'project.auth2', # works well
)
I tracked down the source code and realized that django.db.models.loading.app_models dictionary has a record named 'auth' taken from 'django.contrib.auth' (upon middleware processing I suppose) which prevents my 'auth' application to be used.
Attachments (1)
Change History (12)
comment:1 by , 14 years ago
| Cc: | added |
|---|
comment:2 by , 14 years ago
| Resolution: | → invalid |
|---|---|
| Status: | new → closed |
comment:3 by , 14 years ago
| Resolution: | invalid |
|---|---|
| Status: | closed → reopened |
No! The problem is that I didn't used 'django.contrib.auth' at all! But cannot name my application 'auth'.
My settings.py file:
DEBUG = True
TEMPLATE_DEBUG = DEBUG
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
'NAME': 'seka', # Or path to database file if using sqlite3.
'USER': 'root', # Not used with sqlite3.
'PASSWORD': 'root', # Not used with sqlite3.
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
}
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
)
ROOT_URLCONF = 'seka.urls'
INSTALLED_APPS = (
'seka.auth',
)
My models.py:
from django.db import models
from django.utils.translation import ugettext_lazy as _
# Create your models here.
class User (models.Model):
username = models.CharField(_('username'), max_length=30, unique=True, help_text=_("Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters"))
Bu running 'manage.py sql auth' gives:
BEGIN;
CREATE TABLE `auth_permission` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`name` varchar(50) NOT NULL,
`content_type_id` integer NOT NULL,
`codename` varchar(100) NOT NULL,
UNIQUE (`content_type_id`, `codename`)
)
;
CREATE TABLE `auth_group_permissions` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`group_id` integer NOT NULL,
`permission_id` integer NOT NULL,
UNIQUE (`group_id`, `permission_id`)
)
;
ALTER TABLE `auth_group_permissions` ADD CONSTRAINT `permission_id_refs_id_5886d21f` FOREIGN KEY (`permission_id`) REFERENCES `auth_permission` (`id`);
CREATE TABLE `auth_group` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`name` varchar(80) NOT NULL UNIQUE
)
;
ALTER TABLE `auth_group_permissions` ADD CONSTRAINT `group_id_refs_id_3cea63fe` FOREIGN KEY (`group_id`) REFERENCES `auth_group` (`id`);
CREATE TABLE `auth_user_user_permissions` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`user_id` integer NOT NULL,
`permission_id` integer NOT NULL,
UNIQUE (`user_id`, `permission_id`)
)
;
ALTER TABLE `auth_user_user_permissions` ADD CONSTRAINT `permission_id_refs_id_67e79cb` FOREIGN KEY (`permission_id`) REFERENCES `auth_permission` (`id`);
CREATE TABLE `auth_user_groups` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`user_id` integer NOT NULL,
`group_id` integer NOT NULL,
UNIQUE (`user_id`, `group_id`)
)
;
ALTER TABLE `auth_user_groups` ADD CONSTRAINT `group_id_refs_id_f116770` FOREIGN KEY (`group_id`) REFERENCES `auth_group` (`id`);
CREATE TABLE `auth_user` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`username` varchar(30) NOT NULL UNIQUE,
`first_name` varchar(30) NOT NULL,
`last_name` varchar(30) NOT NULL,
`email` varchar(75) NOT NULL,
`password` varchar(128) NOT NULL,
`is_staff` bool NOT NULL,
`is_active` bool NOT NULL,
`is_superuser` bool NOT NULL,
`last_login` datetime NOT NULL,
`date_joined` datetime NOT NULL
)
;
ALTER TABLE `auth_user_user_permissions` ADD CONSTRAINT `user_id_refs_id_dfbab7d` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`);
ALTER TABLE `auth_user_groups` ADD CONSTRAINT `user_id_refs_id_7ceef80f` FOREIGN KEY (`user_id`) REFERENCES `auth_user`(`id`);
CREATE TABLE `auth_message` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`user_id` integer NOT NULL,
`message` longtext NOT NULL
)
;
ALTER TABLE `auth_message` ADD CONSTRAINT `user_id_refs_id_650f49a6` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`);
-- The following references should be added but depend on non-existent tables:
-- ALTER TABLE `auth_permission` ADD CONSTRAINT `content_type_id_refs_id_728de91f` FOREIGN KEY (`content_type_id`) REFERENCES `django_content_type` (`id`);
COMMIT;
comment:4 by , 14 years ago
| Resolution: | → invalid |
|---|---|
| Status: | reopened → closed |
tl;dr don't call your app "auth" :)
You have django.contrib.auth.middleware.AuthenticationMiddleware in MIDDLEWARE_CLASSES.
By default, this will use django.contrib.auth.backends.ModelBackend as an authentication backend (https://docs.djangoproject.com/en/dev/ref/settings/#authentication-backends).
This backend imports django.contrib.auth.models (https://code.djangoproject.com/browser/django/trunk/django/contrib/auth/backends.py)
Thus, even if you haven't declared django.contrib.auth in INSTALLED_APPS, it gets registered in the application cache, creating a conflict with your app.
I hope this helps!
comment:5 by , 14 years ago
| Resolution: | invalid |
|---|---|
| Status: | closed → reopened |
I think there is a misunderstanding between us...
I didn't used 'django.contrib.auth' at all, look at my second post, please.
There is no 'django.contrib.auth.middleware.AuthenticationMiddleware' in MIDDLEWARE_CLASSES
I raised an exeption at the beginning of 'django.contrib.auth.models'. Look at the exception stack, please:
Traceback (most recent call last):
File "C:\home\dev\seka\seka\manage.py", line 14, in <module>
execute_manager(settings)
File "C:\home\python\lib\site-packages\django\core\management\__init__.py", line 438, in execute_manager
utility.execute()
File "C:\home\python\lib\site-packages\django\core\management\__init__.py", line 379, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "C:\home\python\lib\site-packages\django\core\management\base.py", line 191, in run_from_argv
self.execute(*args, **options.__dict__)
File "C:\home\python\lib\site-packages\django\core\management\base.py", line 219, in execute
self.validate()
File "C:\home\python\lib\site-packages\django\core\management\base.py", line 243, in validate
from django.core.management.validation import get_validation_errors
File "C:\home\python\lib\site-packages\django\core\management\validation.py", line 3, in <module>
from django.contrib.contenttypes.generic import GenericForeignKey, GenericRelation
File "C:\home\python\lib\site-packages\django\contrib\contenttypes\generic.py", line 13, in <module>
from django.contrib.admin.options import InlineModelAdmin, flatten_fieldsets
File "C:\home\python\lib\site-packages\django\contrib\admin\__init__.py", line 6, in <module>
from django.contrib.admin.sites import AdminSite, site
File "C:\home\python\lib\site-packages\django\contrib\admin\sites.py", line 4, in <module>
from django.contrib.admin.forms import AdminAuthenticationForm
File "C:\home\python\lib\site-packages\django\contrib\admin\forms.py", line 4, in <module>
from django.contrib.auth.forms import AuthenticationForm
File "C:\home\python\lib\site-packages\django\contrib\auth\forms.py", line 1, in <module>
from django.contrib.auth.models import User
File "C:\home\python\lib\site-packages\django\contrib\auth\models.py", line 15, in <module>
raise 'AUTH MODELS CALLED'
So 'auth' package was called from 'admin' package which was called from 'contenttypes' which was called from django core.
I didn't included those packages in my settings, but they were called anymore.
Is this ok?
Are the names 'auth', 'admin', 'contenttypes' magic and forbidden to use as an application names?
I attach my zipped example project with this message, hope it will be helpful.
by , 14 years ago
comment:6 by , 14 years ago
| Summary: | my application project.auth takes models from django.contrib.auth → manage.py depends on django.contrib.contenttypes et al. |
|---|---|
| Triage Stage: | Unreviewed → Accepted |
Your original report contained django.contrib.auth.middleware.AuthenticationMiddleware, and I missed the fact that the example you posted later on didn't — sorry about that.
Thanks for your example. It really helped me reproduce the problem quickly. Indeed, I obtain this:
% ./manage.py sql --traceback all Error: One or more models did not validate: auth.permission: 'content_type' has a relation with model <class 'django.contrib.contenttypes.models.ContentType'>, which has either not been installed or is abstract.
And by raising an exception in django.contrib.auth.models, I reproduce your backtrace. It shows that manage.py depends on contenttypes, admin and auth, which is bad because django's core is supposed not to depend on contrib apps.
The root cause of the problem is the fact that since r14563 django.core.management.validation depends on django.contrib.contenttypes. I am going to update the summary to reflect this.
comment:7 by , 14 years ago
comment:8 by , 14 years ago
I could see the validate command calling a specific hook in the app classes (e.g. a validate method) once the app-loading branch lands.
comment:9 by , 14 years ago
| Resolution: | → fixed |
|---|---|
| Status: | reopened → closed |
In [16493]:
(The changeset message doesn't reference this ticket)
This works as advertised: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
It's very hard to remove this limitation in a backwards compatible way because Django references models in many places as
<app_module>.<ModelClass>, which gets translated to<path>.<to>.<app_module>.models.<ModelClass>.