| ============== |
| Managing files |
| ============== |
| |
| This document describes Django's file access APIs for files such as those |
| uploaded by a user. The lower level APIs are general enough that you could use |
| them for other purposes. If you want to handle "static files" (JS, CSS, etc), |
| see :doc:`/howto/static-files/index`. |
| |
| 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 an :class:`~django.db.models.ImageField` 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. |
| |
| .. note:: |
| The file is saved as part of saving the model in the database, so the actual |
| file name used on disk cannot be relied on until after the model has been |
| saved. |
| |
| |
| The ``File`` object |
| =================== |
| |
| Internally, Django uses a :class:`django.core.files.File` instance 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/library/stdtypes.html#bltin-file-objects |
| |
| 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 documented attributes and methods |
| of the :class:`~django.core.files.File` class. |
| |
| Be aware that files created in this way are not automatically closed. |
| The following approach may be used to close files automatically:: |
| |
| >>> from django.core.files import File |
| |
| # Create a Python file object using open() and the with statement |
| >>> with open('/tmp/hello.world', 'w') as f: |
| ... myfile = File(f) |
| ... myfile.write('Hello World') |
| ... |
| >>> myfile.closed |
| True |
| >>> f.closed |
| True |
| |
| Closing files is especially important when accessing file fields in a loop |
| over a large number of objects. If files are not manually closed after |
| accessing them, the risk of running out of file descriptors may arise. This |
| may lead to the following error:: |
| |
| IOError: [Errno 24] Too many open files |
| |
| |
| 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 |
| :doc:`/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 :doc:`/ref/files/storage` for the file storage API. |
| |
| .. _builtin-fs-storage: |
| |
| 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 :setting:`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 :setting:`MEDIA_URL` setting. |
| ====================== =================================================== |
| |
| For example, the following code will store uploaded files under |
| ``/media/photos`` regardless of what your :setting:`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) |
| |
| :doc:`Custom storage systems </howto/custom-file-storage>` work the same way: |
| you can pass them in as the ``storage`` argument to a |
| :class:`~django.db.models.FileField`. |