Opened 2 years ago

Closed 2 years ago

Last modified 15 months ago

#21409 closed Bug (invalid)

Incorrect default BASE_DIR value in project template

Reported by: dmamaev@… 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


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 Changed 2 years ago by dmamaev@…

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Summary changed from Incorrect defatult BASE_DIR value in project template to Incorrect default BASE_DIR value in project template

comment:2 Changed 2 years ago by timo

__file__ returns an absolute path and dirname is used twice to traverse two directories above the file. What happens on your system?

comment:3 Changed 2 years ago by dmamaev@…

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__))

    '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, 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 Changed 2 years ago by aaugustin

  • Resolution set to invalid
  • Status changed from new to 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 Changed 2 years ago by kermit

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 The abspath(dirname(__file__)) solution works for me.

This behaviour of __file__ was also discussed in and

comment:6 Changed 21 months ago by dev@…

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.


comment:7 Changed 15 months ago by hjwp

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__)))

Last edited 15 months ago by hjwp (previous) (diff)
Note: See TracTickets for help on using tickets.
Back to Top