2008-08-24 06:25:40 +08:00
|
|
|
==============
|
|
|
|
Managing files
|
|
|
|
==============
|
|
|
|
|
2013-03-22 18:01:51 +08:00
|
|
|
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
|
2016-01-11 00:48:16 +08:00
|
|
|
them for other purposes. If you want to handle "static files" (JS, CSS, etc.),
|
2013-03-08 03:15:39 +08:00
|
|
|
see :doc:`/howto/static-files/index`.
|
2008-08-24 06:25:40 +08:00
|
|
|
|
|
|
|
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.
|
|
|
|
|
2010-11-27 20:27:43 +08:00
|
|
|
Consider the following model, using an :class:`~django.db.models.ImageField` to
|
|
|
|
store a photo::
|
2008-08-24 06:25:40 +08:00
|
|
|
|
2013-05-18 20:00:52 +08:00
|
|
|
from django.db import models
|
|
|
|
|
2008-08-24 06:25:40 +08:00
|
|
|
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::
|
|
|
|
|
2008-09-14 14:49:28 +08:00
|
|
|
>>> car = Car.objects.get(name="57 Chevy")
|
2008-08-24 06:25:40 +08:00
|
|
|
>>> car.photo
|
2019-10-29 21:13:47 +08:00
|
|
|
<ImageFieldFile: cars/chevy.jpg>
|
2008-08-24 06:25:40 +08:00
|
|
|
>>> car.photo.name
|
2014-03-23 04:30:49 +08:00
|
|
|
'cars/chevy.jpg'
|
2008-08-24 06:25:40 +08:00
|
|
|
>>> car.photo.path
|
2014-03-23 04:30:49 +08:00
|
|
|
'/media/cars/chevy.jpg'
|
2008-08-24 06:25:40 +08:00
|
|
|
>>> car.photo.url
|
2014-03-23 04:30:49 +08:00
|
|
|
'http://media.example.com/cars/chevy.jpg'
|
2008-08-24 06:25:40 +08:00
|
|
|
|
|
|
|
This object -- ``car.photo`` in the example -- is a ``File`` object, which means
|
|
|
|
it has all the methods and attributes described below.
|
|
|
|
|
2011-11-19 23:08:07 +08:00
|
|
|
.. 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.
|
|
|
|
|
2015-03-29 03:14:47 +08:00
|
|
|
For example, you can change the file name by setting the file's
|
|
|
|
:attr:`~django.core.files.File.name` to a path relative to the file storage's
|
|
|
|
location (:setting:`MEDIA_ROOT` if you are using the default
|
|
|
|
:class:`~django.core.files.storage.FileSystemStorage`)::
|
|
|
|
|
|
|
|
>>> import os
|
|
|
|
>>> from django.conf import settings
|
|
|
|
>>> initial_path = car.photo.path
|
|
|
|
>>> car.photo.name = 'cars/chevy_ii.jpg'
|
|
|
|
>>> new_path = settings.MEDIA_ROOT + car.photo.name
|
|
|
|
>>> # Move the file on the filesystem
|
|
|
|
>>> os.rename(initial_path, new_path)
|
|
|
|
>>> car.save()
|
|
|
|
>>> car.photo.path
|
|
|
|
'/media/cars/chevy_ii.jpg'
|
|
|
|
>>> car.photo.path == new_path
|
|
|
|
True
|
2011-11-19 23:08:07 +08:00
|
|
|
|
2019-10-25 20:57:37 +08:00
|
|
|
.. note::
|
|
|
|
|
2020-05-26 00:05:22 +08:00
|
|
|
While :class:`~django.db.models.ImageField` non-image data attributes, such
|
|
|
|
as ``height``, ``width``, and ``size`` are available on the instance, the
|
|
|
|
underlying image data cannot be used without reopening the image. For
|
2019-10-25 20:57:37 +08:00
|
|
|
example::
|
|
|
|
|
|
|
|
>>> from PIL import Image
|
|
|
|
>>> car = Car.objects.get(name='57 Chevy')
|
|
|
|
>>> car.photo.width
|
|
|
|
191
|
|
|
|
>>> car.photo.height
|
|
|
|
287
|
|
|
|
>>> image = Image.open(car.photo)
|
|
|
|
# Raises ValueError: seek of closed file.
|
|
|
|
>>> car.photo.open()
|
|
|
|
<ImageFieldFile: cars/chevy.jpg>
|
|
|
|
>>> image = Image.open(car.photo)
|
|
|
|
>>> image
|
2019-11-11 18:31:57 +08:00
|
|
|
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=191x287 at 0x7F99A94E9048>
|
2019-10-25 20:57:37 +08:00
|
|
|
|
2008-08-24 06:25:40 +08:00
|
|
|
The ``File`` object
|
|
|
|
===================
|
|
|
|
|
2010-12-05 15:35:10 +08:00
|
|
|
Internally, Django uses a :class:`django.core.files.File` instance any time it
|
2016-05-09 06:07:43 +08:00
|
|
|
needs to represent a file.
|
2008-08-24 06:25:40 +08:00
|
|
|
|
2019-06-17 22:54:55 +08:00
|
|
|
Most of the time you'll use a ``File`` that Django's given you (i.e. a file
|
|
|
|
attached to a model as above, or perhaps an uploaded file).
|
2008-08-24 06:25:40 +08:00
|
|
|
|
|
|
|
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()
|
2015-12-24 01:08:40 +08:00
|
|
|
>>> f = open('/path/to/hello.world', 'w')
|
2008-08-24 06:25:40 +08:00
|
|
|
>>> myfile = File(f)
|
|
|
|
|
2010-12-05 15:35:10 +08:00
|
|
|
Now you can use any of the documented attributes and methods
|
|
|
|
of the :class:`~django.core.files.File` class.
|
2008-08-24 06:25:40 +08:00
|
|
|
|
2012-06-07 20:08:46 +08:00
|
|
|
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
|
2015-12-24 01:08:40 +08:00
|
|
|
>>> with open('/path/to/hello.world', 'w') as f:
|
2013-06-15 09:28:17 +08:00
|
|
|
... myfile = File(f)
|
|
|
|
... myfile.write('Hello World')
|
|
|
|
...
|
2012-06-07 20:08:46 +08:00
|
|
|
>>> myfile.closed
|
|
|
|
True
|
|
|
|
>>> f.closed
|
|
|
|
True
|
|
|
|
|
|
|
|
Closing files is especially important when accessing file fields in a loop
|
2013-05-10 19:23:32 +08:00
|
|
|
over a large number of objects. If files are not manually closed after
|
2012-06-07 20:08:46 +08:00
|
|
|
accessing them, the risk of running out of file descriptors may arise. This
|
2013-01-24 04:36:48 +08:00
|
|
|
may lead to the following error::
|
2012-06-07 20:08:46 +08:00
|
|
|
|
2019-01-28 23:01:35 +08:00
|
|
|
OSError: [Errno 24] Too many open files
|
2012-06-07 20:08:46 +08:00
|
|
|
|
|
|
|
|
2008-08-24 06:25:40 +08:00
|
|
|
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
|
2010-08-20 03:27:44 +08:00
|
|
|
:doc:`/howto/custom-file-storage` for information on writing your own file
|
2008-08-24 06:25:40 +08:00
|
|
|
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::
|
|
|
|
|
2008-08-31 18:37:44 +08:00
|
|
|
>>> from django.core.files.base import ContentFile
|
2018-05-13 01:37:42 +08:00
|
|
|
>>> from django.core.files.storage import default_storage
|
2008-08-24 06:25:40 +08:00
|
|
|
|
2019-08-20 18:01:10 +08:00
|
|
|
>>> path = default_storage.save('path/to/file', ContentFile(b'new content'))
|
2008-08-24 06:25:40 +08:00
|
|
|
>>> path
|
2019-08-20 18:01:10 +08:00
|
|
|
'path/to/file'
|
2008-08-24 06:25:40 +08:00
|
|
|
|
2008-12-23 07:21:32 +08:00
|
|
|
>>> default_storage.size(path)
|
2008-08-24 06:25:40 +08:00
|
|
|
11
|
|
|
|
>>> default_storage.open(path).read()
|
2019-08-20 18:01:10 +08:00
|
|
|
b'new content'
|
2008-08-24 06:25:40 +08:00
|
|
|
|
|
|
|
>>> default_storage.delete(path)
|
|
|
|
>>> default_storage.exists(path)
|
|
|
|
False
|
|
|
|
|
2010-08-20 03:27:44 +08:00
|
|
|
See :doc:`/ref/files/storage` for the file storage API.
|
2008-08-24 06:25:40 +08:00
|
|
|
|
2012-11-02 04:11:05 +08:00
|
|
|
.. _builtin-fs-storage:
|
|
|
|
|
2008-08-24 06:25:40 +08:00
|
|
|
The built-in filesystem storage class
|
|
|
|
-------------------------------------
|
|
|
|
|
2014-04-02 16:08:20 +08:00
|
|
|
Django ships with a :class:`django.core.files.storage.FileSystemStorage` class
|
|
|
|
which implements basic local filesystem file storage.
|
2008-08-24 06:25:40 +08:00
|
|
|
|
|
|
|
For example, the following code will store uploaded files under
|
2010-11-27 20:27:43 +08:00
|
|
|
``/media/photos`` regardless of what your :setting:`MEDIA_ROOT` setting is::
|
2008-08-24 06:25:40 +08:00
|
|
|
|
|
|
|
from django.core.files.storage import FileSystemStorage
|
2018-05-13 01:37:42 +08:00
|
|
|
from django.db import models
|
2008-08-24 06:25:40 +08:00
|
|
|
|
|
|
|
fs = FileSystemStorage(location='/media/photos')
|
|
|
|
|
|
|
|
class Car(models.Model):
|
|
|
|
...
|
|
|
|
photo = models.ImageField(storage=fs)
|
|
|
|
|
2010-11-27 20:27:43 +08:00
|
|
|
: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`.
|
2020-03-31 18:12:39 +08:00
|
|
|
|
|
|
|
Using a callable
|
|
|
|
----------------
|
|
|
|
|
|
|
|
.. versionadded:: 3.1
|
|
|
|
|
|
|
|
You can use a callable as the :attr:`~django.db.models.FileField.storage`
|
|
|
|
parameter for :class:`~django.db.models.FileField` or
|
|
|
|
:class:`~django.db.models.ImageField`. This allows you to modify the used
|
|
|
|
storage at runtime, selecting different storages for different environments,
|
|
|
|
for example.
|
|
|
|
|
|
|
|
Your callable will be evaluated when your models classes are loaded, and must
|
|
|
|
return an instance of :class:`~django.core.files.storage.Storage`.
|
|
|
|
|
|
|
|
For example::
|
|
|
|
|
|
|
|
from django.conf import settings
|
|
|
|
from django.db import models
|
|
|
|
from .storages import MyLocalStorage, MyRemoteStorage
|
|
|
|
|
|
|
|
|
|
|
|
def select_storage():
|
|
|
|
return MyLocalStorage() if settings.DEBUG else MyRemoteStorage()
|
|
|
|
|
|
|
|
|
|
|
|
class MyModel(models.Model):
|
|
|
|
my_file = models.FileField(storage=select_storage)
|