管理文件

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

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

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

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

    任何 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 对象,这意味着它拥有下面所描述的所有方法和属性。

    注解

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

    例如,您可以通过将文件名设置为相对于文件存储位置的路径来更改文件名(如果你正在使用默认的 ,则为 MEDIA_ROOT )。

    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. True

    虽然 无图像数据属性,比如 height, width, and size 在实例上可用,但不重新打开图片的时候,无法使用底层图像数据。比如:

    在内部,Django 在任何需要表示文件的时候使用 django.core.files.File

    大部分情况下你只需要使用 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)

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

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

    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将如何以及在哪里存储文件的决策委托给文件存储系统。这个对象实际上理解文件系统、打开和读取文件等。

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

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

    1. >>> path = default_storage.save('path/to/file', ContentFile(b'new content'))
    2. >>> path
    3. 'path/to/file'
    4. >>> default_storage.size(path)
    5. 11
    6. >>> default_storage.open(path).read()
    7. b'new content'
    8. >>> default_storage.delete(path)
    9. >>> default_storage.exists(path)
    10. 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 参数传递给 。

    New in Django 3.1.

    You can use a callable as the storage parameter for or 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 .

    例如: