#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?