#12288 closed Cleanup/optimization (fixed)
Validate that values in INSTALLED_APPS are unique
Reported by: | Owned by: | Susan Tan | |
---|---|---|---|
Component: | Core (Other) | Version: | dev |
Severity: | Normal | Keywords: | sprint200912 |
Cc: | Ivan Kolodyazhny | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Docs for INSTALLED_APPS says:
"A tuple of strings designating all applications that are enabled in this Django installation. Each string should be a full Python path to a Python package that contains a Django application, as created by django-admin.py startapp."
Fact that application name must be unique in INSTALLED_APPS otherwise Django will go crazy isn't mentioned at all.
It really should be in bold.
Attachments (1)
Change History (39)
comment:1 by , 15 years ago
Triage Stage: | Unreviewed → Accepted |
---|
by , 15 years ago
Attachment: | settings.diff added |
---|
comment:2 by , 15 years ago
Has patch: | set |
---|---|
Needs documentation: | set |
Needs tests: | set |
Resolution: | → fixed |
Status: | new → closed |
Replying to Piotr Czachur <zimnyx@gmail.com>:
Docs for INSTALLED_APPS says:
"A tuple of strings designating all applications that are enabled in this Django installation. Each string should be a full Python path to a Python package that contains a Django application, as created by django-admin.py startapp."
Fact that application name must be unique in INSTALLED_APPS otherwise Django will go crazy isn't mentioned at all.
It really should be in bold.
comment:4 by , 15 years ago
Needs documentation: | unset |
---|---|
Needs tests: | unset |
Resolution: | fixed |
Status: | closed → reopened |
Attached patch. (Closed ticket by mistake. noobi)
comment:5 by , 15 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
comment:6 by , 15 years ago
Keywords: | sprint200912 added |
---|
comment:7 by , 15 years ago
comment:8 by , 15 years ago
comment:9 by , 15 years ago
Has patch: | unset |
---|---|
Triage Stage: | Ready for checkin → Accepted |
The uniqueness has now been reinforced in docs; I'm leaving this ticket open as a placeholder for the need for better validation of the contents of INSTALLED_APPS
comment:10 by , 15 years ago
Component: | Documentation → Core framework |
---|
comment:11 by , 14 years ago
Severity: | → Normal |
---|---|
Type: | → Cleanup/optimization |
comment:14 by , 12 years ago
Status: | reopened → new |
---|
comment:15 by , 11 years ago
Summary: | Application name must be unique in a project - should be emphasized in docs → Validate that values in INSTALLED_APPS are unique |
---|
Updating summary per Russ's last comment.
comment:16 by , 11 years ago
@Timo, I'm fairly new to writing tests in Django. Should the new test be added in tests/settings_tests?
In principle, the test would look like this (and feel free to correct me if I'm wrong):
from settings import INSTALLED_APPS def test_unique_installed_apps(TestCase): self.assertEqual(len(INSTALLED_APPS), len(set(INSTALLED_APPS))
I'm not quite sure of the package names and the details that this test would require. What are your thoughts?
comment:17 by , 11 years ago
This would be a new feature (validating that the values in a user's settings.INSTALLED_APPS
are unique), not just a test. I'm not sure where the best place to put this new code would be.
comment:18 by , 11 years ago
Perhaps I should ask on the core django mentorship list, of which Jeremy is in charge of?
follow-up: 20 comment:19 by , 11 years ago
As answered on Django Core Membership (message has been deleted for no reasons):
There's already a check in django.conf.Settings
to make sure INSTALLED_APPS
is not a string so I'd suggest you add this check at the same place.
Concerning the tests I suggest you take a look at the settings_tests
test application. However you might have to move the check to BaseSettings.__setattr__
if you want to use the testing strategy used in settings_tests.TrailingSlashURLTests
.
comment:20 by , 11 years ago
Thanks for the advice. I understand now. I have an additional question related to debugging. I often like to put print statements to check the values and the variable types. Is there a way to do that in the django project? For example, in django/conf/init.py, I want to print out the result of line 124: mod = importlib.import_module(self.SETTINGS_MODULE)
Are there debugging tools I should be aware of that can be particularly helpful for this project?
comment:21 by , 11 years ago
I've made a PR. This PR is in initial stages of development: https://github.com/django/django/pull/1445 I haven't tested any of this code that I wrote. It's a work in progress. Now that I think more about this ticket, am I really writing a test for a test?
comment:22 by , 11 years ago
Regarding debugging, if you put a print statement in there, that code will be run when using runserver
for example.
The logic in the PR looks correct. As Simon said, if you put the logic in BaseSettings.__setattr__
, you should be able to use a similar testing style as settings_tests.TrailingSlashURLTests
.
comment:23 by , 11 years ago
Updated the PR based on the feedback here. Unit tests pass. Let me know if there's anything I left out or forgot to consider. PR is here: https://github.com/django/django/pull/1445/files
comment:24 by , 11 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:25 by , 11 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
comment:26 by , 11 years ago
There's a typo in the test class name - tiny pull request at https://github.com/django/django/pull/1461.
comment:28 by , 11 years ago
Resolution: | fixed |
---|---|
Status: | closed → new |
Looking at the documentation, it appears we didn't make the validation strict enough: "The application names (that is, the final dotted part of the path to the module containing models.py) defined in INSTALLED_APPS must be unique. For example, you can’t include both django.contrib.auth and myproject.auth in INSTALLED_APPS."
comment:29 by , 11 years ago
Easy pickings: | set |
---|
comment:30 by , 11 years ago
Cc: | added |
---|
I've updated tests and fix for this ticket in https://github.com/django/django/pull/1626
comment:31 by , 11 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:32 by , 11 years ago
Latest commit is very much backward incompatible and is IMO a bad idea.
I can't run master anymore, and fixing it would require renaming tons of packages.
"X.Y.Z" is *not* the same as "A.B.Z".
Also lot of third party apps would now be conflicting with each other, particularly the namespaced ones like "mezzanine" or "armstrong".
What's the gain exactly? I've been using this for years and never encountered any issues.
comment:33 by , 11 years ago
Django assumes in some places that app_name.model_name is unique key (IIRC things like contenttypes, permissions and app-cache assume this). I think if you happen to have somepackage.app1.User and otherpackage.app1.User you will have problems.
That being said backwards compatibility could be a bigger concern that making sure the above doesn't happen.
comment:34 by , 11 years ago
Also worth noting that this patch does not actually prevent the issue discussed - you can just as easily create a User
model with an app_label
of auth
, and have just as much of a problem. Can we not apply this validation at the app cache level if this is what we're trying to avoid? The first patch is good as it catches easy mistakes, the second seems overkill. I'm not sure it's a pattern we should encourage, perhaps print a warning on server start, but I think it should be allowed.
comment:36 by , 11 years ago
Easy pickings: | unset |
---|---|
Resolution: | fixed |
Status: | closed → new |
Here's a discussion on the mailing list that looks into why app names have to be unique.
https://groups.google.com/forum/#!topic/django-developers/gzBWU_fUdgc/discussion
For now, I've reverted the latest commit given the backwards incompatibility concerns.
comment:37 by , 11 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Closing this -- if someone feels the app cache validation described by Marc in comment 34 is worthwhile, please open a new ticket.
comment:38 by , 11 years ago
I fixed this properly in the app loading project, after introducing the ability to relabel an application, which provides an exit path for people who rely on the current lax behavior.
There may also be some room validate this formally on startup, but at the very least, this should be documented.