mirror of
				https://github.com/django/django.git
				synced 2025-11-03 21:25:09 +00:00 
			
		
		
		
	Thanks simon29 for report, and freakboy3742, floledermann, jacob, claudep and collinanderson for discussing the task.
		
			
				
	
	
		
			186 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			186 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
==============
 | 
						|
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::
 | 
						|
 | 
						|
    from django.db import models
 | 
						|
 | 
						|
    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
 | 
						|
    'cars/chevy.jpg'
 | 
						|
    >>> car.photo.path
 | 
						|
    '/media/cars/chevy.jpg'
 | 
						|
    >>> car.photo.url
 | 
						|
    '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.
 | 
						|
 | 
						|
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
 | 
						|
 | 
						|
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: https://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
 | 
						|
    '/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 :class:`django.core.files.storage.FileSystemStorage` class
 | 
						|
which implements basic local filesystem file storage.
 | 
						|
 | 
						|
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`.
 |