上传文件和上传处理程序 — Django 文档

来自菜鸟教程
Django/docs/3.2.x/ref/files/uploads
跳转至:导航、​搜索

上传的文件和上传处理程序

上传的文件

class UploadedFile

在文件上传过程中,实际文件数据存储在 request.FILES 中。 该词典中的每个条目都是一个 UploadedFile 对象(或一个子类)——一个上传文件的包装器。 您通常会使用以下方法之一来访问上传的内容:

UploadedFile.read()
从文件中读取整个上传的数据。 小心使用这种方法:如果上传的文件很大,如果您尝试将其读入内存,它可能会使您的系统不堪重负。 你可能想用 chunks() 代替; 见下文。
UploadedFile.multiple_chunks(chunk_size=None)
如果上传的文件大到需要读取多个块,则返回 True。 默认情况下,这将是大于 2.5 兆字节的任何文件,但这是可配置的; 见下文。
UploadedFile.chunks(chunk_size=None)

返回文件块的生成器。 如果 multiple_chunks() 为 True,则应在循环中使用此方法而不是 read()。

在实践中,始终使用 chunks() 通常是最简单的。 循环使用 chunks() 而不是使用 read() 可确保大文件不会占用系统内存。

以下是 UploadedFile 的一些有用属性:

UploadedFile.name
上传文件的名称(例如 my_file.txt)。
UploadedFile.size
上传文件的大小(以字节为单位)。
UploadedFile.content_type
随文件上传的内容类型标头(例如 text/plain 或 application/pdf)。 与用户提供的任何数据一样,您不应该相信上传的文件实际上是这种类型。 您仍然需要验证文件是否包含内容类型标头声明的内容 - “信任但验证”。
UploadedFile.content_type_extra
包含传递给 content-type 标头的额外参数的字典。 这通常由代表您拦截和处理文件上传的服务(例如 Google App Engine)提供。 因此,您的处理程序可能不会收到上传的文件内容,而是收到文件的 URL 或其他指针(请参阅 RFC 2388)。
UploadedFile.charset
对于 text/* 内容类型,字符集(即 utf8) 由浏览器提供。 同样,“信任但验证”是这里的最佳策略。

笔记

与常规 Python 文件一样,您可以通过迭代上传的文件来逐行读取文件:

for line in uploadedfile:
    do_something_with(line)

使用 通用换行符 分割行。 以下被认为是行尾:Unix 行尾约定 '\n'、Windows 约定 '\r\n' 和旧的 Macintosh 约定 '\r'。


UploadedFile 的子类包括:

class TemporaryUploadedFile
上传到临时位置的文件(即 流到磁盘)。 此类由 TemporaryFileUploadHandler 使用。 除了 UploadedFile 中的方法,它还有一个额外的方法:
TemporaryUploadedFile.temporary_file_path()
返回临时上传文件的完整路径。
class InMemoryUploadedFile
上传到内存中的文件(即 流到内存)。 此类由 MemoryFileUploadHandler 使用。


内置上传处理程序

MemoryFileUploadHandler 和 TemporaryFileUploadHandler 一起提供了 Django 的默认文件上传行为,将小文件读入内存,将大文件读入磁盘。 它们位于 django.core.files.uploadhandler。

class MemoryFileUploadHandler

文件上传处理程序将上传流式传输到内存中(用于小文件)。

class TemporaryFileUploadHandler

使用 TemporaryUploadedFile 将数据流式传输到临时文件的上传处理程序。


编写自定义上传处理程序

class FileUploadHandler

所有文件上传处理程序都应该是 django.core.files.uploadhandler.FileUploadHandler 的子类。 您可以在任何地方定义上传处理程序。

必需的方法

自定义文件上传处理程序 必须 定义以下方法:

FileUploadHandler.receive_data_chunk(raw_data, start)

从文件上传接收数据“块”。

raw_data 是包含上传数据的字节串。

start 是文件中这个 raw_data 块开始的位置。

您返回的数据将被输入到后续上传处理程序的 receive_data_chunk 方法中。 这样,一个处理程序可以成为其他处理程序的“过滤器”。

从 receive_data_chunk 返回 None 以短路剩余的上传处理程序以获取此块。 如果您自己存储上传的数据并且不希望将来的处理程序存储数据的副本,这将非常有用。

如果您引发 StopUpload 或 SkipFile 异常,上传将中止或文件将被完全跳过。

FileUploadHandler.file_complete(file_size)

当文件完成上传时调用。

处理程序应返回一个 UploadedFile 对象,该对象将存储在 request.FILES 中。 处理程序也可能返回 None 以指示 UploadedFile 对象应该来自后续上传处理程序。


可选方法

自定义上传处理程序还可以定义以下任何可选方法或属性:

FileUploadHandler.chunk_size

“块”的大小,以字节为单位,Django 应该存储到内存中并输入处理程序。 也就是说,该属性控制送入 FileUploadHandler.receive_data_chunk 的块的大小。

为了获得最佳性能,块大小应可被 4 整除,并且大小不应超过 2 GB(231 字节)。 当多个处理程序提供多个块大小时,Django 将使用任何处理程序定义的最小块大小。

默认为 64*210 字节,或 64 KB。

FileUploadHandler.new_file(field_name, file_name, content_type, content_length, charset, content_type_extra)

新文件上传开始的回调信号。 在将任何数据馈送到任何上传处理程序之前调用此方法。

field_name 是文件 <input> 字段的字符串名称。

file_name 是浏览器提供的文件名。

content_type 是浏览器提供的 MIME 类型 - 例如 'image/jpeg'。

content_length 是浏览器给出的图片长度。 有时这不会被提供,而是 None。

charset 是字符集(即 utf8) 由浏览器给出。 像 content_length 一样,有时不会提供。

content_type_extra 是来自 content-type 头文件的额外信息。 参见 UploadedFile.content_type_extra。

此方法可能会引发 StopFutureHandlers 异常以防止将来的处理程序处理此文件。

FileUploadHandler.upload_complete()
整个上传(所有文件)已完成的回调信号。
FileUploadHandler.upload_interrupted()

3.2 版中的新功能。

上传被中断的回调信号,例如 当用户在文件上传过程中关闭浏览器时。

FileUploadHandler.handle_raw_input(input_data, META, content_length, boundary, encoding)

允许处理程序完全覆盖原始 HTTP 输入的解析。

input_data 是一个类文件对象,支持 read()-ing。

META 与 request.META 是同一个对象。

content_length为input_data中数据的长度。 不要从 input_data 读取超过 content_length 个字节。

boundary 是此请求的 MIME 边界。

encoding 是请求的编码。

如果要继续上传处理,则返回 None,如果要直接返回适合请求的新数据结构,则返回 (POST, FILES) 元组。