Opened 9 years ago
Last modified 3 years ago
#26401 new New feature
Allow auth machinery to be used without installing auth app
Reported by: | Matt Johnson | Owned by: | |
---|---|---|---|
Component: | contrib.auth | Version: | 1.9 |
Severity: | Normal | Keywords: | auth |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Django projects should be able to use the auth machinery (like django.contrib.auth.middleware.AuthenticationMiddleware and django.contrib.auth.context_processors.auth) without having django.contrib.auth in INSTALLED_APPS
See
https://groups.google.com/forum/#!topic/django-developers/2DzLBbk8w-w
This ticket is for resolving the current issue in 1.9. I also want to write a test or two to prevent this issue from happening in the future.
Attachments (1)
Change History (29)
comment:1 by , 9 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:2 by , 9 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:3 by , 9 years ago
Has patch: | set |
---|
comment:4 by , 9 years ago
Needs tests: | set |
---|
comment:5 by , 8 years ago
Owner: | removed |
---|---|
Status: | assigned → new |
De-assigning so it's clear this is available for a PyCon sprinter to finish up with tests.
comment:6 by , 8 years ago
Owner: | set to |
---|---|
Status: | new → assigned |
comment:8 by , 8 years ago
FWIW I don't see a lot of value in adding this constraint. Implementing it requires a fragile and untestable combination of inner imports to avoid touching the models module.
If the only problem is to avoid creating tables in the database, add a MIGRATION_MODULES
entry for the auth app that points to an empty package. I never tried it but I think it should work.
If this workaround is confirmed to work, I propose to close this ticket as wontfix.
comment:9 by , 8 years ago
Interesting idea. It works:
MIGRATION_MODULES = { 'auth': None }
My complaint was driven by the unnecessary clutter in my database when using a custom user model. So now that there is a reasonable solution, I'm fine with closing this.
comment:10 by , 8 years ago
Resolution: | → wontfix |
---|---|
Status: | assigned → closed |
comment:12 by , 8 years ago
I found the above to be insufficient. Adding MIGRATION_MODULES
as the only change to avoid the auth tables fails during migrations with the following trace:
Traceback (most recent call last): File ".../manage.py", line 9, in <module> execute_from_command_line(sys.argv) File ".../venv/lib64/python3.5/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line utility.execute() File ".../venv/lib64/python3.5/site-packages/django/core/management/__init__.py", line 359, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File ".../venv/lib64/python3.5/site-packages/django/core/management/base.py", line 305, in run_from_argv self.execute(*args, **cmd_options) File ".../venv/lib64/python3.5/site-packages/django/core/management/base.py", line 356, in execute output = self.handle(*args, **options) File ".../venv/lib64/python3.5/site-packages/django/core/management/commands/migrate.py", line 222, in handle self.verbosity, self.interactive, connection.alias, apps=post_migrate_apps, plan=plan, File ".../venv/lib64/python3.5/site-packages/django/core/management/sql.py", line 53, in emit_post_migrate_signal **kwargs File ".../venv/lib64/python3.5/site-packages/django/dispatch/dispatcher.py", line 191, in send response = receiver(signal=self, sender=sender, **named) File ".../venv/lib64/python3.5/site-packages/django/contrib/auth/management/__init__.py", line 75, in create_permissions "content_type", "codename" File ".../venv/lib64/python3.5/site-packages/django/db/models/query.py", line 256, in __iter__ self._fetch_all() File ".../venv/lib64/python3.5/site-packages/django/db/models/query.py", line 1085, in _fetch_all self._result_cache = list(self.iterator()) File ".../venv/lib64/python3.5/site-packages/django/db/models/query.py", line 125, in __iter__ for row in compiler.results_iter(): File ".../venv/lib64/python3.5/site-packages/django/db/models/sql/compiler.py", line 789, in results_iter results = self.execute_sql(MULTI) File ".../venv/lib64/python3.5/site-packages/django/db/models/sql/compiler.py", line 835, in execute_sql cursor.execute(sql, params) File ".../venv/lib64/python3.5/site-packages/django/db/backends/utils.py", line 79, in execute return super(CursorDebugWrapper, self).execute(sql, params) File ".../venv/lib64/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute return self.cursor.execute(sql, params) File ".../venv/lib64/python3.5/site-packages/django/db/utils.py", line 94, in __exit__ six.reraise(dj_exc_type, dj_exc_value, traceback) File ".../venv/lib64/python3.5/site-packages/django/utils/six.py", line 685, in reraise raise value.with_traceback(tb) File ".../venv/lib64/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute return self.cursor.execute(sql, params) django.db.utils.ProgrammingError: relation "auth_permission" does not exist LINE 1: ...ntent_type_id", "auth_permission"."codename" FROM "auth_perm...
This fails becuase the auth's AppConfig
adds a post_migrate callback that requires the auth_permission
table to exist. A project could avoid this by overriding the auth's AppConfig
. I think this could be easier for projects if the auth's AppConfig
was split into two classes, one base version that can be used without the auth tables and one that matches the current implementation. This would be a backwards compatible change that would allow the MIGRATION_MODULES
change noted above. For example:
class BaseAuthConfig(AppConfig): name = 'django.contrib.auth' verbose_name = _("Authentication and Authorization") def ready(self): checks.register(check_user_model, checks.Tags.models) class AuthConfig(BaseAuthConfig): def ready(self): post_migrate.connect( create_permissions, dispatch_uid="django.contrib.auth.management.create_permissions" ) checks.register(check_models_permissions, checks.Tags.models)
comment:13 by , 8 years ago
Resolution: | wontfix |
---|---|
Status: | closed → new |
comment:14 by , 8 years ago
PR implementing the AppConfig
s described above.
Not sure how to best add a test for this though. Looking for advice. Details in the PR.
comment:16 by , 8 years ago
Easy pickings: | unset |
---|---|
Patch needs improvement: | set |
comment:17 by , 8 years ago
Patch needs improvement: | unset |
---|---|
Triage Stage: | Accepted → Ready for checkin |
comment:19 by , 8 years ago
I've hit another snag with the MIGRATION_MODULES = {'auth': None}
approach. (Sorry, is it better to reopen this ticket or file a new one?)
The auth.Permission
model has a fk on ContentType
. Due to this, when deleting a ContentType
(such as with the remove_stale_contenttypes
command) queries against the missing auth_permission
table can occur.
Not sure how best to handle this scenario. IIUC, as long as auth is in INSTALLED_APPS
, the models will be loaded and this FK will cause an issue.
Here is a stack trace when deleting a stale content type
Traceback (most recent call last): File "/usr/lib64/python3.5/runpy.py", line 170, in _run_module_as_main "__main__", mod_spec) File "/usr/lib64/python3.5/runpy.py", line 85, in _run_code exec(code, run_globals) File "/home/jon/devel/django/django/__main__.py", line 9, in <module> management.execute_from_command_line() File "/home/jon/devel/django/django/core/management/__init__.py", line 366, in execute_from_command_line utility.execute() File "/home/jon/devel/django/django/core/management/__init__.py", line 358, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/home/jon/devel/django/django/core/management/base.py", line 294, in run_from_argv self.execute(*args, **cmd_options) File "/home/jon/devel/django/django/core/management/base.py", line 345, in execute output = self.handle(*args, **options) File "/home/jon/devel/django/django/contrib/contenttypes/management/commands/remove_stale_contenttypes.py", line 46, in handle collector.collect([ct]) File "/home/jon/devel/django/django/db/models/deletion.py", line 218, in collect elif sub_objs: File "/home/jon/devel/django/django/db/models/query.py", line 260, in __bool__ self._fetch_all() File "/home/jon/devel/django/django/db/models/query.py", line 1072, in _fetch_all self._result_cache = list(self.iterator()) File "/home/jon/devel/django/django/db/models/query.py", line 54, in __iter__ results = compiler.execute_sql() File "/home/jon/devel/django/django/db/models/sql/compiler.py", line 847, in execute_sql cursor.execute(sql, params) File "/home/jon/devel/django/django/db/backends/utils.py", line 64, in execute return self.cursor.execute(sql, params) File "/home/jon/devel/django/django/db/utils.py", line 94, in __exit__ six.reraise(dj_exc_type, dj_exc_value, traceback) File "/home/jon/devel/django/django/utils/six.py", line 685, in reraise raise value.with_traceback(tb) File "/home/jon/devel/django/django/db/backends/utils.py", line 64, in execute return self.cursor.execute(sql, params) File "/home/jon/devel/django/django/db/backends/sqlite3/base.py", line 334, in execute return Database.Cursor.execute(self, query, params) django.db.utils.OperationalError: no such table: auth_permission
by , 8 years ago
Attachment: | ticket-26401-remove-stale-contenttypes.patch added |
---|
Test case for remove_stale_contenttypes with auth migrations disabled
comment:20 by , 8 years ago
Has patch: | unset |
---|---|
Keywords: | 1.11 added |
Triage Stage: | Ready for checkin → Accepted |
Type: | Bug → New feature |
It's appropriate to reopen a ticket if the fix hasn't been released yet.
comment:21 by , 8 years ago
Resolution: | fixed |
---|---|
Status: | closed → new |
Reopening until the above issue is handled.
comment:22 by , 8 years ago
Has patch: | set |
---|
I'm unable to think of a sensible solution to the ContentType
auth.Permission
dependency issue. Therefore, I'm suggesting to revert my previous PR as using auth without migrations will not fully work.
comment:23 by , 8 years ago
It seems like you basically want an apps.register.Apps.unregister_model()
method or some way of telling Django not to setup relations for a given model. This might not be trivial, so if you want to revert for now, that's fine with me.
comment:25 by , 8 years ago
Resolution: | fixed |
---|---|
Status: | closed → new |
Reopening. The revert commit was merged.
comment:26 by , 8 years ago
Has patch: | unset |
---|---|
Keywords: | 1.11 removed |
comment:27 by , 3 years ago
Owner: | removed |
---|---|
Status: | new → assigned |
comment:28 by , 3 years ago
Status: | assigned → new |
---|
https://github.com/django/django/pull/6420