2008-08-09 04:59:02 +08:00
|
|
|
==============
|
|
|
|
Managing files
|
|
|
|
==============
|
|
|
|
|
|
|
|
**New in Django development version**
|
|
|
|
|
|
|
|
This document describes Django's file access APIs.
|
|
|
|
|
|
|
|
By default, Django stores files locally, using the ``MEDIA_ROOT`` and
|
|
|
|
``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`_
|
|
|
|
.. _settings: ../settings/
|
|
|
|
|
|
|
|
Using files in models
|
|
|
|
=====================
|
|
|
|
|
|
|
|
When you use a `FileField`_ or `ImageField`_, Django provides a set of APIs you can use to deal with that file.
|
|
|
|
|
|
|
|
.. _filefield: ../model-api/#filefield
|
|
|
|
.. _imagefield: ../model-api/#imagefield
|
|
|
|
|
|
|
|
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.object.get(name="57 Chevy")
|
|
|
|
>>> car.photo
|
|
|
|
<ImageFieldFile: chevy.jpg>
|
|
|
|
>>> car.photo.name
|
|
|
|
u'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
|
|
|
|
|
|
|
|
Creating ``File`` instances
|
|
|
|
---------------------------
|
|
|
|
|
|
|
|
Most of the time you'll simply use a ``File`` that Django's given you (i.e. a
|
|
|
|
file attached to an model as above, or perhaps an `uploaded file`_).
|
|
|
|
|
|
|
|
.. _uploaded file: ../uploading_files/
|
|
|
|
|
|
|
|
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 defined below.
|
|
|
|
|
|
|
|
``File`` attributes and methods
|
|
|
|
-------------------------------
|
|
|
|
|
|
|
|
Django's ``File`` has the following attributes and methods:
|
|
|
|
|
|
|
|
``File.path``
|
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
The absolute path to the file's location on a local filesystem.
|
|
|
|
|
|
|
|
Custom `file storage systems`_ may not store files locally; files stored on
|
|
|
|
these systems will have a ``path`` of ``None``.
|
|
|
|
|
|
|
|
``File.url``
|
|
|
|
~~~~~~~~~~~~
|
|
|
|
|
|
|
|
The URL where the file can be retrieved. This is often useful in templates_; for
|
|
|
|
example, a bit of a template for displaying a ``Car`` (see above) might look
|
|
|
|
like::
|
|
|
|
|
|
|
|
<img src='{{ car.photo.url }}' alt='{{ car.name }}' />
|
|
|
|
|
|
|
|
.. _templates: ../templates/
|
|
|
|
|
|
|
|
``File.size``
|
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
The size of the file in bytes.
|
|
|
|
|
|
|
|
``File.open(mode=None)``
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Open or reopen the file (which by definition also does ``File.seek(0)``). The
|
|
|
|
``mode`` argument allows the same values as Python's standard ``open()``.
|
|
|
|
|
|
|
|
When reopening a file, ``mode`` will override whatever mode the file was
|
|
|
|
originally opened with; ``None`` means to reopen with the original mode.
|
|
|
|
|
|
|
|
``File.read(num_bytes=None)``
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Read content from the file. The optional ``size`` is the number of bytes to
|
|
|
|
read; if not specified, the file will be read to the end.
|
|
|
|
|
|
|
|
``File.__iter__()``
|
|
|
|
~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Iterate over the file yielding one line at a time.
|
|
|
|
|
|
|
|
``File.chunks(chunk_size=None)``
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Iterate over the file yielding "chunks" of a given size. ``chunk_size`` defaults
|
|
|
|
to 64 KB.
|
|
|
|
|
|
|
|
This is especially useful with very large files since it allows them to be
|
|
|
|
streamed off disk and avoids storing the whole file in memory.
|
|
|
|
|
|
|
|
``File.multiple_chunks(chunk_size=None)``
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Returns ``True`` if the file is large enough to require multiple chunks to
|
|
|
|
access all of its content give some ``chunk_size``.
|
|
|
|
|
|
|
|
``File.write(content)``
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Writes the specified content string to the file. Depending on the storage system
|
|
|
|
behind the scenes, this content might not be fully committed until ``close()``
|
|
|
|
is called on the file.
|
|
|
|
|
|
|
|
``File.close()``
|
|
|
|
~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Close the file.
|
|
|
|
|
|
|
|
.. TODO: document the rest of the File methods.
|
|
|
|
|
|
|
|
Additional ``ImageField`` attributes
|
|
|
|
------------------------------------
|
|
|
|
|
|
|
|
``File.width`` and ``File.height``
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
These attributes provide the dimensions of the image.
|
|
|
|
|
|
|
|
Additional methods on files attached to objects
|
|
|
|
-----------------------------------------------
|
|
|
|
|
|
|
|
Any ``File`` that's associated with an object (as with ``Car.photo``, above)
|
|
|
|
will also have a couple of extra methods:
|
|
|
|
|
|
|
|
``File.save(name, content, save=True)``
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Saves a new file with the file name and contents provided. This will not replace
|
|
|
|
the existing file, but will create a new file and update the object to point to
|
|
|
|
it. If ``save`` is ``True``, the model's ``save()`` method will be called once
|
|
|
|
the file is saved. That is, these two lines::
|
|
|
|
|
|
|
|
>>> car.photo.save('myphoto.jpg', contents, save=False)
|
|
|
|
>>> car.save()
|
|
|
|
|
|
|
|
are the same as this one line::
|
|
|
|
|
|
|
|
>>> car.photo.save('myphoto.jpg', contents, save=True)
|
|
|
|
|
|
|
|
``File.delete(save=True)``
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Remove the file from the model instance and delete the underlying file. The
|
|
|
|
``save`` argument works as above.
|
|
|
|
|
|
|
|
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 `DEFAULT_FILE_STORAGE setting`_;
|
|
|
|
if you don't explicitly provide a storage system, this is the one that will be
|
|
|
|
used.
|
|
|
|
|
|
|
|
.. _default_file_storage setting: ../settings/#default-file-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 ``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
|
|
|
|
|
2008-08-09 22:17:54 +08:00
|
|
|
fs = FileSystemStorage(location='/media/photos')
|
2008-08-09 04:59:02 +08:00
|
|
|
|
|
|
|
class Car(models.Model):
|
|
|
|
...
|
|
|
|
photo = models.ImageField(storage=fs)
|
|
|
|
|
|
|
|
`Custom storage systems`_ work the same way: you can pass them in as the
|
|
|
|
``storage`` argument to a ``FileField``.
|
|
|
|
|
|
|
|
.. _custom storage systems: `writing a custom 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
|
|
|
|
|
|
|
|
>>> path = default_storage.save('/path/to/file', 'new content')
|
|
|
|
>>> path
|
|
|
|
u'/path/to/file'
|
|
|
|
|
|
|
|
>>> default_storage.filesize(path)
|
|
|
|
11
|
|
|
|
>>> default_storage.open(path).read()
|
|
|
|
'new content'
|
|
|
|
|
|
|
|
>>> default_storage.delete(path)
|
|
|
|
>>> default_storage.exists(path)
|
|
|
|
False
|
|
|
|
|
|
|
|
Storage objects define the following methods:
|
|
|
|
|
|
|
|
``Storage.exists(name)``
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
``True`` if a file exists given some ``name``.
|
|
|
|
|
2008-08-10 16:19:21 +08:00
|
|
|
``Storage.path(name)``
|
2008-08-09 04:59:02 +08:00
|
|
|
~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
The local filesystem path where the file can be opened using Python's standard
|
|
|
|
``open()``. For storage systems that aren't accessible from the local
|
|
|
|
filesystem, this will raise ``NotImplementedError`` instead.
|
|
|
|
|
|
|
|
``Storage.size(name)``
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Returns the total size, in bytes, of the file referenced by ``name``.
|
|
|
|
|
|
|
|
``Storage.url(name)``
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Returns the URL where the contents of the file referenced by ``name`` can be
|
|
|
|
accessed.
|
|
|
|
|
|
|
|
``Storage.open(name, mode='rb')``
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Opens the file given by ``name``. Note that although the returned file is
|
|
|
|
guaranteed to be a ``File`` object, it might actually be some subclass. In the
|
|
|
|
case of remote file storage this means that reading/writing could be quite slow,
|
|
|
|
so be warned.
|
|
|
|
|
|
|
|
``Storage.save(name, content)``
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Saves a new file using the storage system, preferably with the name specified.
|
|
|
|
If there already exists a file with this name ``name``, the storage system may
|
|
|
|
modify the filename as necessary to get a unique name. The actual name of the
|
|
|
|
stored file will be returned.
|
|
|
|
|
|
|
|
``Storage.delete(name)``
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Deletes the file referenced by ``name``. This method won't raise an exception if
|
|
|
|
the file doesn't exist.
|
|
|
|
|
|
|
|
Writing a custom storage system
|
|
|
|
===============================
|
|
|
|
|
|
|
|
If you need to provide custom file storage -- a common example is storing files
|
|
|
|
on some remote system -- you can do so by defining a custom storage class.
|
|
|
|
You'll need to follow these steps:
|
|
|
|
|
|
|
|
#. Your custom storage system must be a subclass of
|
|
|
|
``django.core.files.storage.Storage``::
|
|
|
|
|
|
|
|
from django.core.files.storage import Storage
|
|
|
|
|
|
|
|
class MyStorage(Storage):
|
|
|
|
...
|
|
|
|
|
|
|
|
#. Django must be able to instantiate your storage system without any arguments.
|
|
|
|
This means that any settings should be taken from ``django.conf.settings``::
|
|
|
|
|
|
|
|
from django.conf import settings
|
|
|
|
from django.core.files.storage import Storage
|
|
|
|
|
|
|
|
class MyStorage(Storage):
|
|
|
|
def __init__(self, option=None):
|
|
|
|
if not option:
|
|
|
|
option = settings.CUSTOM_STORAGE_OPTIONS
|
|
|
|
...
|
|
|
|
|
|
|
|
#. Your storage class must implement the ``_open()`` and ``_save()`` methods,
|
|
|
|
along with any other methods appropriate to your storage class. See below for
|
|
|
|
more on these methods.
|
|
|
|
|
|
|
|
In addition, if your class provides local file storage, it must override
|
|
|
|
the ``path()`` method.
|
|
|
|
|
|
|
|
Custom storage system methods
|
|
|
|
-----------------------------
|
|
|
|
|
|
|
|
Your custom storage system may override any of the storage methods explained
|
|
|
|
above in `storage objects`_. However, it's usually better to use the hooks
|
|
|
|
specifically designed for custom storage objects. These are:
|
|
|
|
|
|
|
|
``_open(name, mode='rb')``
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
**Required**.
|
|
|
|
|
|
|
|
Called by ``Storage.open()``, this is the actual mechanism the storage class
|
|
|
|
uses to open the file. This must return a ``File`` object, though in most cases,
|
|
|
|
you'll want to return some subclass here that implements logic specific to the
|
|
|
|
backend storage system.
|
|
|
|
|
|
|
|
``_save(name, content)``
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Called by ``Storage.save()``. The ``name`` will already have gone through
|
|
|
|
``get_valid_name()`` and ``get_available_name()``, and the ``content`` will be a
|
|
|
|
``File`` object itself. No return value is expected.
|
|
|
|
|
|
|
|
``get_valid_name(name)``
|
|
|
|
------------------------
|
|
|
|
|
|
|
|
Returns a filename suitable for use with the underlying storage system. The
|
|
|
|
``name`` argument passed to this method is the original filename sent to the
|
|
|
|
server, after having any path information removed. Override this to customize
|
|
|
|
how non-standard characters are converted to safe filenames.
|
|
|
|
|
|
|
|
The code provided on ``Storage`` retains only alpha-numeric characters, periods
|
|
|
|
and underscores from the original filename, removing everything else.
|
|
|
|
|
|
|
|
``get_available_name(name)``
|
|
|
|
----------------------------
|
|
|
|
|
|
|
|
Returns a filename that is available in the storage mechanism, possibly taking
|
|
|
|
the provided filename into account. The ``name`` argument passed to this method
|
|
|
|
will have already cleaned to a filename valid for the storage system, according
|
|
|
|
to the ``get_valid_name()`` method described above.
|
|
|
|
|
|
|
|
The code provided on ``Storage`` simply appends underscores to the filename
|
|
|
|
until it finds one that's available in the destination directory.
|