[Fixed]-Django 1.6: How to access static files in view


Instead of joining the STATIC_ROOT with the filename, use the staticfiles_storage interface instead. This will also work with remote static files like S3/django-storages.

from django.contrib.staticfiles.storage import staticfiles_storage

url = staticfiles_storage.url('data/foobar.csv')

With staticfiles_storage you can also do simple file operations like open, delete, save.



The particular staticfiles storage backend you’ve configured will provide both a path method and a url method.

from django.contrib.staticfiles.storage import staticfiles_storage
p = staticfiles_storage.path('data/foobar.csv')
content = p.readlines()
# manipulate content

The .url method returns the same value as Django’s static built-in

url = static('data/foobar.csv')


When you deploy a Django application to Heroku, or when you manually run manage.py collectstatic task, all the static assets will be copied to your STATIC_ROOT directory. Therefore you should use:

file_path = os.path.join(settings.STATIC_ROOT, 'data/foobar.csv')


STATIC_ROOT = 'staticfiles' is your problem. From the docs, STATIC_ROOT is:

The absolute path to the directory where collectstatic will collect static files for deployment.

Currently, you don’t even have a path listed there…


Your static files are not at the same place when you are in "dev" or "prod".
In dev, you use the django "runserver" command which will serve your static file with "original" files (eg : myproject/src/appname/static/appname/images/plop.jpeg)

In production mode, you must use the "collectstatic" django command which will copy those original file in a "direct public http access folder" (eg : /static/appname/images/plop.jpeg for an http access)

But original files are still at the same place (myproject/src/appname/static/appname/images/plop.jpeg), so your view can access those original file directly.

If you know in which app the file your are looking for is, it is very simple. If you want to use the "static overwrite" mecanims of Django, have a look to its functions to get the "final" static file (for exemple, is it myproject/python-env/lib/python2.7/site-packages/coolapp/static/coolapp/images/plop.jpeg or myproject/src/myapp/static/coolapp/images/plop.jpeg)

I recommend to read the Django Doc about static finders to better understand how it works : https://docs.djangoproject.com/en/3.1/ref/settings/#std:setting-STATICFILES_FINDERS

PS : "HTTP path" and "python path" are not the same 😉


Just had the same problem. Don’t know if this is the best solution.

In settings.py I created two paths for switching between productive and development. I need to uncomment when deploying the site.

#STATIC_ROOT = '/home/DimiDev/RESite/static'
STATIC_ROOT = 'realestate/static'

And in my python file, as already stated in this post.

from django.contrib.staticfiles.storage import staticfiles_storage
file_path = staticfiles_storage.path('realestate/ml/2xgBoosting_max.sav')

My structure for this file:



Let me tell you what I did, I made an app in which I had to read a CSV file.

I made the main project directory with django-startproject command and then made an app.
In the root I made a folder named static and inside that, I placed the CSV file.

Now in my views.py

All other settings were default and this worked for me!


What you are trying to do can be achieved the following way.
First as your settings.py file has this base path:

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

You can get files in your static directory this way:

url = os.path.join(settings.BASE_DIR, 'static/data/foobar.csv')
os.path.isfile(url) # True

Leave a comment