muhuk's blog

Nature, to Be Commanded, Must Be Obeyed

November 30, 2011

Working with files in Django - Part 3

First part of this article is here.

How to add STATIC files

You will most likely add STATIC files to your source code repository. As they are likely to be hardcoded in your code and templates it is a good idea to keep those and your STATIC files in sync.

Your STATIC files are collected (found and copied or symlinked) with the help of finders. This collection process might be a little confusing for you. Basically you don’t need to worry about where your files are copied, you just need to maintain the files in the locations I mention below. Collection process consolidates all your STATIC files for you, and it does it automatically.

If you are developing a reusable app place your STATIC files under the static directory. Your app directory should look like this:

$ ls -1
models.py
static/
templates/
views.py

If you are developing a project absolute filesystem paths listed in your STATICFILES_DIRS setting will be collected:

>>> from django.conf import settings
>>> settings.STATICFILES_DIRS
('/opt/myproject/src/project/static',)

One important thing to note, as I mentioned in the first part, is to set your STATIC_ROOT outside of your project directory. This is the location where all the STATIC files found will be consolidated. Making this directory independent from your project installation enabled its reuse.

How to upload MEDIA files

MEDIA files are typically uploaded by users when the project is online and a reference is stored in a model field. While this is true most of the time, MEDIA files can be generated by code and/or a reference can be provided in some other way that doesn’t involve models. But these edge cases are out of the scope of this post.

The easiest way to allow users upload their files is to use a FileField or ImageField on a model and derive a form from it:

from django.db import models
from django.forms.models import modelform_factory


class MediaModel(models.Model):
    media_file = models.FileField(upload_to='user_media')


MediaForm = modelform_factory(MediaModel)

You can then use this form to provide upload functionality:

def media_create(request):
    if request.method == "POST":
        form = MediaForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse('media-list'))
    else:
        form = MediaForm()
    return render_to_response('usermedia/create/html', {'form': form})

Of course it is better to use a generic CreateView now we have them with Django 1.3. I wanted to emphasize one point and avoid the complexities of a class based view; you must pass request.FILES to the form’s constructor. Actually this is a good practice whether or not your form has an file field.

As in the case with STATIC files, MEDIA_ROOT should be in a location seperate from your project files. If you delete your project directory you would also lose MEDIA files otherwise.

Conclusion

This concludes Working with files in Django - Part 1. I hope these posts are helpful to you. Once you are comfortable working with files I strongly recommend you to take a look at Django Compressor

If you have any questions, suggestions or corrections feel free to drop me a line.