Django: Private File Upload and Serving


30th September 2010 in Coding Tags: django, programming, python, security, upload

In this post I want to share with you a quick tip that I couldn't learn just by browsing and reading the Django documentation (yea sometimes the solution is easier to find than what we think).

The standard Django FileFields assume you want to upload a file in a subdirectory of MEDIA_ROOT, what if you want to upload the file in a private directory above the web root, not accessible via http?
How can you serve the files then?

1. Enter Filesystem Storage Class

As explained in the Django Documentation, consider the following model:


from django.db import models

class Myapp(models.Model):
    """ Your application """
    file = models.FileField(upload_to='files')

And let's state for example that the apache web root is "/var/www/yoursite/public_html/" and we want the files to be uploaded in "/var/www/yoursite/private/".


from django.db import models
from import FileSystemStorage

fs = FileSystemStorage(location="/var/www/yoursite/private/")

class Myapp(models.Model):
    """ Your application """
    file = models.FileField(storage=fs)

You can even specify the "upload_to" parameter and django will upload the file in the subdirectory of  "/var/www/yoursite/private/".

To make things nicer you can define the location in your settings file and then import the value in your file:

PRIVATE_DIR = '/var/www/yoursite/private/'


from django.db import models
from import FileSystemStorage
from settings import PRIVATE_DIR
fs = FileSystemStorage(location=PRIVATE_DIR)
class Myapp(models.Model):
    """ Your application """
    file = models.ImageField(upload_to='images', storage=fs)

This last examples tells django to upload images in "/var/www/yoursite/private/images/".

Serving files: enter django-filetransfers

To save time I used the interesting app django-filetransfers.

  1. Simply download it, unzip it (or use "tar xvf" if you download it as a gzip archive), cd into the folder and install the script by using "python install".
  2. Add "filetransfers" in your INSTALLED_APP tuple in
  3. Create a view that will serve the file:


from django.shortcuts import get_object_or_404
from filetransfers.api import serve_file
from myapp.models import Myapp

def download(request, id):

    # get the object by id or raise a 404 error
    object = get_object_or_404(Myapp, pk=id)

    return serve_file(request, object.file)

It was much easier than what I thought in the beginning.

What I've really learned today

Sometimes using google to find quick answers is not the right way. It is better to look at the documentation with more attention.

With this article bytheway, I hope I will help other people to solve this problem quickly.

Thanks to Blaaman and Xavier Ordoquy in the Django Users Google Group. See question on Google Groups.



  1. 1.

    Esam said:

    ( on 9th of May 2011 at 16:02 )

    if i want this app to upload pic directly from the internet eg: .. what shoud i do in order to obtain this result ?

  2. 2.

    Federico Capoano said:

    ( on 9th of May 2011 at 16:06 )

    This script doesn't serve this scope.

  3. 3.

    maldives said:

    ( on 13th of September 2011 at 19:09 )

    very good... i agree with google thing i have been searching google for a week for this function... but its really simple... i was looking more for security

    thank man
    have a good day

  4. 4.

    Jon said:

    ( on 25th of October 2011 at 04:00 )

    Thanks, this is a nice, simple explanation of serving private files. Very helpful.

  5. 5.

    laurent said:

    ( on 14th of August 2012 at 16:41 )

    like said Jon

    Thanks, this is a nice, simple explanation of serving private files. Very helpful.

  6. 6.

    ricardo said:

    ( on 17th of April 2013 at 16:07 )

    Thanks a lot. This post was very helpful for me. It works nice !

  7. 7.

    Stephanie said:

    ( on 6th of April 2015 at 23:11 )

    I've designated the new location to where the file should be uploaded and that works great!
    But, in my template, when I try to display the image, it doesn't work? I had originally been using
    src="{{STATIC_URL}}upload/{{ dataset.dataset_image }}"

    but, now that I changed the location, I just hard coded the location in the template for now. Why doesn't the uploaded image display??
    src="/Users/me/projects/uploadimages/{{ dataset.dataset_image }}"

Leave your comment


Let's be social

Popular posts

Latest Comments

  1. When I ߋriginalⅼy commented I seem to have clicked the -Notify me when new comments aгe added- checkbox and from now on each time a comment іs adԁed I get 4 emails wіth the same comment. Ⲣerhaps there is an easy method you can remove ...

    By youjizz in Django Tagging Autocomplete Tag-It

  2. Hey there I am so thrilled I found your weƄ site, I really found you by accident, whiⅼe I was reseɑrϲhing on Digg for something else, Nonetheless I am here now and woսld jսst like to say many tһanks fοг a tremendous post and a ...

    By youporn in Django Tagging Autocomplete Tag-It

  3. Sexy photo galleries, daily updated pics breast boob tit nipple porn hair style porn bb08 australia porn fee porn no signon man in a relationship view porn

    By barbarakc3 in OpenWISP at IETF Bangkok

  4. Girls of Desire: All babes in one place, crazy, art porn movies harry potter lesbiand porn videos free lesbain porn vedios free porn movie dumps teen bi porn

    By lorraineum16 in OpenWISP at IETF Bangkok

  5. Sexy photo galleries, daily updated pics spy toilet poop porn long pron free movies the fastest porn torrent quicktime free lesbian porn alice 3d porn

    By alanawy11 in OpenWISP at IETF Bangkok

Popular Tags

battlemesh censorship creativity criptography django event fosdem google-summer-of-code ibiza inspiration javascript jquery linux nemesisdesign netjson ninux nodeshot open-source openwisp openwrt performance photo programming python security staticgenerator talk upload wifi wireless-community