Using Python’s os.path, how do I go up one directory?
I recently upgrade Django from v1.3.1 to v1.4. In my old settings.py I have TEMPLATE_DIRS = ( os.path.join(os.path.dirname( __file__ ), 'templates').replace('\\', '/'), # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. ) This will point to /Users/hobbes3/Sites/mysite/templates, but because Django v1.4 moved the project folder to the same level as the app folders, my settings.py file is now in /Users/hobbes3/Sites/mysite/mysite/ instead of /Users/hobbes3/Sites/mysite/. So actually my question is now twofold: How do I use os.path to look at a directory one level above from __file__. In other words, I want /Users/hobbes3/Sites/mysite/mysite/settings.py to find /Users/hobbes3/Sites/mysite/templates using relative paths. Should I be keeping the template folder (which has cross-app templates, like admin, registration, etc.) at the project /User/hobbes3/Sites/mysite level or at /User/hobbes3/Sites/mysite/mysite?
os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'templates'))
As far as where the templates folder should go, I don’t know since Django 1.4 just came out and I haven’t looked at it yet. You should probably ask another question on SE to solve that issue.
You can also use
normpath to clean up the path, rather than
abspath. However, in this situation, Django expects an absolute path rather than a relative path.
For cross platform compatability, use
os.pardir instead of
To get the folder of a file just use:
To get a folder up just use
You might want to check if
__file__ is a symlink:
if os.path.islink(__file__): path = os.readlink (__file__)
You want exactly this:
BASE_DIR = os.path.join( os.path.dirname( __file__ ), '..' )
If you are using Python 3.4 or newer, a convenient way to move up multiple directories is
from pathlib import Path full_path = "path/to/directory" str(Path(full_path).parents) # "path/to" str(Path(full_path).parents) # "path" str(Path(full_path).parents) # "."
Personally, I’d go for the function approach
def get_parent_dir(directory): import os return os.path.dirname(directory) current_dirs_parent = get_parent_dir(os.getcwd())
I think the easiest thing to do is just to reuse dirname()
So you can call
os.path.dirname(os.path.dirname( __file__ ))
if you file is at /Users/hobbes3/Sites/mysite/templates/method.py
This will return “/Users/hobbes3/Sites/mysite”
from os.path import dirname, realpath, join join(dirname(realpath(dirname(__file__))), 'templates')
If you happen to “copy”
settings.py through symlinking, @forivall’s answer is better:
~user/ project1/ mysite/ settings.py templates/ wrong.html project2/ mysite/ settings.py -> ~user/project1/settings.py templates/ right.html
The method above will ‘see’
wrong.html while @forivall’s method will see
In the absense of symlinks the two answers are identical.
This might be useful for other cases where you want to go x folders up. Just run
walk_up_folder(path, 6) to go up 6 folders.
def walk_up_folder(path, depth=1): _cur_depth = 1 while _cur_depth < depth: path = os.path.dirname(path) _cur_depth += 1 return path
For a paranoid like me, I’d prefer this one
TEMPLATE_DIRS = ( __file__.rsplit('/', 2) + '/templates', )
n folders up… run
import os def up(n, nth_dir=os.getcwd()): while n != 0: nth_dir = os.path.dirname(nth_dir) n -= 1 return nth_dir
Of course: simply use
- Database Administration Tutorials
- Programming Tutorials & IT News
- Linux & DevOps World
- Entertainment & General News
- Games & eSport