管理文件

    默认情况下,Django 使用 MEDIA_ROOT 和 设置本地存储。下面的例子假设你在使用这些默认设置。

    不过,Django 提供编写自定义 file storage systems 的方法,允许你完全自定义 Django 存储文件的位置和方式。这篇文档的后半部分描述了存储系统的工作方式。

    当你使用 或 ImageField 时,Django 提供了一组处理文件的API。

    考虑下面的模型,使用 来存储照片:

    任何 Car 实例将拥有一个 photo 属性,你可以使用它来获取附加照片的详情:

    1. >>> car = Car.objects.get(name="57 Chevy")
    2. >>> car.photo
    3. <ImageFieldFile: cars/chevy.jpg>
    4. >>> car.photo.name
    5. 'cars/chevy.jpg'
    6. >>> car.photo.path
    7. '/media/cars/chevy.jpg'
    8. >>> car.photo.url
    9. 'http://media.example.com/cars/chevy.jpg'

    car.photo 是一个 File 对象,这意味着它拥有下面所描述的所有方法和属性。

    注解

    文件在数据库中作为保存模型的一部分,因此在模型被保存之前,不能依赖磁盘上使用的实际文件名。

    1. >>> import os
    2. >>> from django.conf import settings
    3. >>> initial_path = car.photo.path
    4. >>> car.photo.name = 'cars/chevy_ii.jpg'
    5. >>> new_path = settings.MEDIA_ROOT + car.photo.name
    6. >>> # Move the file on the filesystem
    7. >>> car.save()
    8. >>> car.photo.path
    9. '/media/cars/chevy_ii.jpg'
    10. >>> car.photo.path == new_path

    注解

    While 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 example:

    在内部,Django 在任何需要表示文件的时候使用 。

    大部分情况下你只需要使用 Django 提供的 File (即附加到上述模型的文件或已经上传的文件)。

    如果你需要自己构建 File ,最简单的方法是使用 Python 内置的 file 对象创建一个:

    1. >>> from django.core.files import File
    2. # Create a Python file object using open()
    3. >>> f = open('/path/to/hello.world', 'w')
    4. >>> myfile = File(f)

    现在你可以使用 File 类的任何属性和方法。

    注意在这里创建的文件不会自动关闭。下面的方式可以用来自动关闭文件:

    1. >>> from django.core.files import File
    2. # Create a Python file object using open() and the with statement
    3. >>> with open('/path/to/hello.world', 'w') as f:
    4. ... myfile = File(f)
    5. ... myfile.write('Hello World')
    6. ...
    7. >>> myfile.closed
    8. True
    9. >>> f.closed
    10. True

    在对大量对象进行循环访问文件字段时,关闭文件尤为重要。如果文件在访问后不能手动关闭,可能会出现文件描述符溢出的风险。

    Django 的默认文件存储通过 配置;如果你不显式地提供存储系统,这里会使用默认配置。

    参阅下面内置默认文件存储系统的细节,也可以查看 How to write a custom storage class 来了解编写自己的文件存储系统的信息。

    虽然大部分时间你可以使用 File 对象(将该文件委托给合适的存储),但你可以直接使用文件存储系统。你可以创建一些自定义文件存储类的示例,或使用通常更有用的全局默认存储系统:

    1. >>> from django.core.files.storage import default_storage
    2. >>> path = default_storage.save('path/to/file', ContentFile(b'new content'))
    3. >>> path
    4. 'path/to/file'
    5. >>> default_storage.size(path)
    6. 11
    7. >>> default_storage.open(path).read()
    8. b'new content'
    9. >>> default_storage.delete(path)
    10. >>> default_storage.exists(path)
    11. False

    查看 来了解文件存储API。

    Django 附带一个 django.core.files.storage.FileSystemStorage 类,这个类实现基础的本地文件系统文件存储。

    例如,下面的代码将存储上传文件到 /media/photos 而会忽略你在 的设置:

    1. from django.core.files.storage import FileSystemStorage
    2. from django.db import models
    3. fs = FileSystemStorage(location='/media/photos')
    4. class Car(models.Model):
    5. ...

    自定义存储系统( Custom storage systems )的工作方式也一样:将它们作为 storage 参数传递给 。

    你可以使用callable作为 FileField 或 的 storage 参数。它允许你在运行时修改存储参数,不同环境选择不同存储,例如。

    例如: