#21409 closed Bug (invalid)
Incorrect default BASE_DIR value in project template
| Reported by: | Owned by: | nobody | |
|---|---|---|---|
| Component: | Uncategorized | Version: | 1.6 |
| Severity: | Normal | Keywords: | settings, BASE_DIR |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | yes | UI/UX: | no |
Description
It seems to be a mistype:
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
Obviously the BASE_DIR must be an absolute path:
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
Change History (7)
comment:1 by , 12 years ago
| Summary: | Incorrect defatult BASE_DIR value in project template → Incorrect default BASE_DIR value in project template |
|---|
comment:2 by , 12 years ago
comment:3 by , 12 years ago
os.path.abspath function returns normalized absolute path on different platforms, so it more safely.
For example current defaults with os.path.pardir:
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, os.path.pardir, 'db', 'db.sqlite3'),
}
}
Thensyncdb command starts with these settings it returns OperationalError: unable to open database file on Windows 7 with ActivePython 2.7.2.5, but works perfectly then BASE_DIR is os.path.abspath(os.path.dirname(__file__)).
This solution also works on Debian 7 with Python 2.7.2.
comment:4 by , 12 years ago
| Resolution: | → invalid |
|---|---|
| Status: | new → closed |
Thanks for the suggestion. However I believe the current implementation is correct for its intended use case.
If your Django project is stored in a version control system, BASE_DIR should be the root directory. The name BASE_DIR makes it clear that you shouldn't navigate to the parent directory.
If you deviate from the expected repository layout, you should adjust your settings file accordingly.
comment:5 by , 12 years ago
I'm running Ubuntu 13.04 with Python 2.7.5 and am also experiencing problems, because __file__ returns a relative path and my templates are not found as I reported in https://code.djangoproject.com/ticket/21409. The abspath(dirname(__file__)) solution works for me.
This behaviour of __file__ was also discussed in http://stackoverflow.com/questions/7116889/python-file-attribute-absolute-or-relative and http://stackoverflow.com/questions/7783308/os-path-dirname-file-returns-empty.
comment:6 by , 12 years ago
The double dirname solution works in most cases, but not all - e.g. _ _file_ _ being relative. Also using os.path.dirname on a directory feels unintuitive and anti-semantic.
Unfortunately the right way to do this (from my point of view) is pretty hard to read and complex due to function nesting:
BASE_PATH = os.path.abspath( os.path.normpath( os.path.join( os.path.dirname(__file__), os.path.pardir ) ) )
or shorter:
p = os.path BASE_PATH = p.abspath( p.normpath( p.join( p.dirname(__file__), p.pardir ) ) )
Maybe we should investigate what people use and how many have problems with this preset.
Regards
Hugo
comment:7 by , 11 years ago
As of Python 3.4, file will always return an absolute path. Could that be an argument for adding the abspath as the innermost call, to make sure that the behaviour in 3.4+ is the same as previous versions?
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
https://docs.python.org/3.4/whatsnew/3.4.html#other-language-changes
__file__returns an absolute path anddirnameis used twice to traverse two directories above thesettings.pyfile. What happens on your system?