#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 , 11 years ago
Summary: | Incorrect defatult BASE_DIR value in project template → Incorrect default BASE_DIR value in project template |
---|
comment:2 by , 11 years ago
comment:3 by , 11 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 , 11 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 , 11 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 , 11 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 , 10 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 anddirname
is used twice to traverse two directories above thesettings.py
file. What happens on your system?