#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 Changed 13 years ago by
Triage Stage: | Unreviewed → Accepted |
---|
Changed 13 years ago by
Attachment: | settings.diff added |
---|
comment:2 Changed 13 years ago by
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 Changed 13 years ago by
Needs documentation: | unset |
---|---|
Needs tests: | unset |
Resolution: | fixed |
Status: | closed → reopened |
Attached patch. (Closed ticket by mistake. noobi)
comment:5 Changed 13 years ago by
Triage Stage: | Accepted → Ready for checkin |
---|
comment:6 Changed 13 years ago by
Keywords: | sprint200912 added |
---|
comment:7 Changed 13 years ago by
comment:8 Changed 13 years ago by
comment:9 Changed 13 years ago by
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 Changed 13 years ago by
Component: | Documentation → Core framework |
---|
comment:11 Changed 12 years ago by
Severity: | → Normal |
---|---|
Type: | → Cleanup/optimization |
comment:14 Changed 10 years ago by
Status: | reopened → new |
---|
comment:15 Changed 10 years ago by
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 Changed 10 years ago by
@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 Changed 10 years ago by
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 Changed 10 years ago by
Perhaps I should ask on the core django mentorship list, of which Jeremy is in charge of?
comment:19 follow-up: 20 Changed 10 years ago by
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 Changed 10 years ago by
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 Changed 10 years ago by
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 Changed 10 years ago by
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 Changed 10 years ago by
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 Changed 10 years ago by
Owner: | changed from nobody to Susan Tan |
---|---|
Status: | new → assigned |
comment:25 Changed 10 years ago by
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
comment:26 Changed 10 years ago by
There's a typo in the test class name - tiny pull request at https://github.com/django/django/pull/1461.
comment:28 Changed 10 years ago by
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 Changed 10 years ago by
Easy pickings: | set |
---|
comment:30 Changed 10 years ago by
Cc: | Ivan Kolodyazhny added |
---|
I've updated tests and fix for this ticket in https://github.com/django/django/pull/1626
comment:31 Changed 10 years ago by
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:32 Changed 10 years ago by
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 Changed 10 years ago by
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 Changed 10 years ago by
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 Changed 10 years ago by
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 Changed 10 years ago by
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 Changed 9 years ago by
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.