Code

Opened 8 months ago

Closed 8 months ago

Last modified 4 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

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

Attachments (0)

Change History (6)

comment:1 Changed 8 months 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 8 months ago by timo

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

comment:3 Changed 8 months 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__))

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 Changed 8 months 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 8 months 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 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 Changed 4 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.

Regards
Hugo

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.