28

I want to open a file from a Django app using open(). The problem is that open() seems to use whatever directory from which I run the runserver command as the root.

E.g. if I run the server from a directory called foo like this

$pwd
/Users/foo
$python myapp/manage.py runserver

open() uses foo as the root directory.

If I do this instead

$cd myapp
$pwd
/Users/foo/myapp
$python manage.py runserver

myapp will be the root.

Let's say my folder structure looks like this

foo/myapp/anotherapp

I would like to be able to open a file located at foo/myapp/anotherapp from a script also located at foo/myapp/anotherapp simply by saying

file = open('./baz.txt')

Now, depending on where I run the server from, I have to say either

file = open('./myapp/anotherapp/baz.txt')

or

file = open('./anotherapp/baz.txt')
Paul Hunter
  • 4,453
  • 3
  • 25
  • 31

3 Answers3

52

The solution has been described in the Favorite Django Tips&Tricks question. The solution is as follows:

import os
module_dir = os.path.dirname(__file__)  # get current directory
file_path = os.path.join(module_dir, 'baz.txt')

Which does exactly what you mentioned.

Ps. Please do not overwrite file variable, it is one of the builtins.

Community
  • 1
  • 1
Tadeck
  • 132,510
  • 28
  • 152
  • 198
  • 1
    Thanks again. Obviously Python is not my normal weapon of choice. – Paul Hunter Mar 14 '12 at 23:22
  • This was just what I needed for my own issue. Thanks! – odedbd Jun 27 '13 at 11:52
  • What if you need to go one step inner. i mean what if baz.txt file is inside some folder in module_dir lets say foo/baz.txt? – A.J. Feb 12 '14 at 10:11
  • @user570826: Either try `file_path = os.path.join(module_dir, 'foo/baz.txt')` or `file_path = os.path.join(module_dir, 'foo', 'baz.txt')`. – Tadeck Feb 12 '14 at 21:29
  • can you tell my why this works .? why must use module dir by os.path.dirname(__file__) – zzy Nov 07 '18 at 06:59
2

I had a similar case. From inside my views.py I needed to open a file sitting in a directory at the same level of my app:

-- myapp
 -- views.py     # Where I need to open the file
-- testdata
 -- test.txt     # File to be opened

To solve I used the BASE_DIR settings variable to reference the project path as follows

...
from django.conf import settings
...

file_path = os.path.join(settings.BASE_DIR, 'testdata/test.txt')
yaach
  • 386
  • 2
  • 3
1

I think I found the answer through another stack overflow question (yes, I did search before asking...)

I now do this

pwd = os.path.dirname(__file__)
file = open(pwd + '/baz.txt')
Paul Hunter
  • 4,453
  • 3
  • 25
  • 31
  • Just FYI: You can also do this: `import socket`, then you can use `socket.gethostname()` to determine hostname of the system you're on. Set up your path based on which hostname is returned. – Furbeenator Mar 14 '12 at 23:03
  • 3
    @PaulHunter: Instead of `pwd + '/baz.txt'` you should use `os.path.join(pwd, 'baz.txt')`. – Tadeck Mar 14 '12 at 23:08