.. _topics-files:

==============
Managing files
==============

.. versionadded:: 1.0

This document describes Django's file access APIs.

By default, Django stores files locally, using the :setting:`MEDIA_ROOT` and
:setting:`MEDIA_URL` settings. The examples below assume that you're using these
defaults.

However, Django provides ways to write custom `file storage systems`_ that
allow you to completely customize where and how Django stores files. The
second half of this document describes how these storage systems work.

.. _file storage systems: `File storage`_

Using files in models
=====================

When you use a :class:`~django.db.models.FileField` or
:class:`~django.db.models.ImageField`, Django provides a set of APIs you can use
to deal with that file.

Consider the following model, using a ``FileField`` to store a photo::

    class Car(models.Model):
        name = models.CharField(max_length=255)
        price = models.DecimalField(max_digits=5, decimal_places=2)
        photo = models.ImageField(upload_to='cars')

Any ``Car`` instance will have a ``photo`` attribute that you can use to get at
the details of the attached photo::

    >>> car = Car.objects.get(name="57 Chevy")
    >>> car.photo
    <ImageFieldFile: chevy.jpg>
    >>> car.photo.name
    u'cars/chevy.jpg'
    >>> car.photo.path
    u'/media/cars/chevy.jpg'
    >>> car.photo.url
    u'http://media.example.com/cars/chevy.jpg'

This object -- ``car.photo`` in the example -- is a ``File`` object, which means
it has all the methods and attributes described below.

The ``File`` object
===================

Internally, Django uses a ``django.core.files.File`` any time it needs to
represent a file. This object is a thin wrapper around Python's `built-in file
object`_ with some Django-specific additions.

.. _built-in file object: http://docs.python.org/lib/bltin-file-objects.html

Most of the time you'll simply use a ``File`` that Django's given you (i.e. a
file attached to a model as above, or perhaps an uploaded file).

If you need to construct a ``File`` yourself, the easiest way is to create one
using a Python built-in ``file`` object::

    >>> from django.core.files import File

    # Create a Python file object using open()
    >>> f = open('/tmp/hello.world', 'w')
    >>> myfile = File(f)

Now you can use any of the ``File`` attributes and methods documented in
:ref:`ref-files-file`.

File storage
============

Behind the scenes, Django delegates decisions about how and where to store files
to a file storage system. This is the object that actually understands things
like file systems, opening and reading files, etc.

Django's default file storage is given by the :setting:`DEFAULT_FILE_STORAGE`
setting; if you don't explicitly provide a storage system, this is the one that
will be used.

See below for details of the built-in default file storage system, and see
:ref:`howto-custom-file-storage` for information on writing your own file
storage system.

Storage objects
---------------

Though most of the time you'll want to use a ``File`` object (which delegates to
the proper storage for that file), you can use file storage systems directly.
You can create an instance of some custom file storage class, or -- often more
useful -- you can use the global default storage system::

    >>> from django.core.files.storage import default_storage
    >>> from django.core.files.base import ContentFile

    >>> path = default_storage.save('/path/to/file', ContentFile('new content'))
    >>> path
    u'/path/to/file'

    >>> default_storage.size(path)
    11
    >>> default_storage.open(path).read()
    'new content'

    >>> default_storage.delete(path)
    >>> default_storage.exists(path)
    False

See :ref:`ref-files-storage` for the file storage API. 

The built-in filesystem storage class
-------------------------------------

Django ships with a built-in ``FileSystemStorage`` class (defined in
``django.core.files.storage``) which implements basic local filesystem file
storage. Its initializer takes two arguments:

======================  ===================================================
Argument                Description
======================  ===================================================
``location``            Optional. Absolute path to the directory that will
                        hold the files. If omitted, it will be set to the
                        value of your ``MEDIA_ROOT`` setting.
``base_url``            Optional. URL that serves the files stored at this
                        location. If omitted, it will default to the value
                        of your ``MEDIA_URL`` setting.
======================  ===================================================

For example, the following code will store uploaded files under
``/media/photos`` regardless of what your ``MEDIA_ROOT`` setting is::

    from django.db import models
    from django.core.files.storage import FileSystemStorage

    fs = FileSystemStorage(location='/media/photos')

    class Car(models.Model):
        ...
        photo = models.ImageField(storage=fs)

:ref:`Custom storage systems <howto-custom-file-storage>` work the same way: you
can pass them in as the ``storage`` argument to a ``FileField``.
