---
title: "上传的文件和上传处理程序"
version: 4.2
locale: zh-hans
source: https://docs.djangoproject.com/zh-hans/4.2/ref/files/uploads/
canonical: https://djangodocs.dev/zh-hans/4.2/ref/files/uploads/
---
# 上传的文件和上传处理程序

## 上传的文件

#### `class UploadedFile`

在文件上传过程中，实际的文件数据存储在 [`request.FILES`](/zh-hans/4.2/ref/request-response/#django.http.HttpRequest.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**](https://datatracker.ietf.org/doc/html/rfc2388.html#section-5.3)）。

#### `UploadedFile.charset`

对于 `text/*` 内容类型，浏览器提供的字符集（即 `utf8`）。同样，“信任但验证” 是这里的最佳政策。

> **Note**
>
> 像普通的 Python 文件一样，你可以通过迭代上传的文件来逐行读取文件：
>
> ```
> for line in uploadedfile:
>     do_something_with(line)
> ```
>
> 使用 [**通用换行符**](https://peps.python.org/pep-0278/) 来分割行。以下是公认的行结束方式：Unix 的行末约定 `'\n'`，Windows 的约定 `'\r\n'`，以及旧的 Macintosh 约定 `'\r'`。

`UploadedFile` 的子类包括：

#### `class TemporaryUploadedFile`

一个文件上传到一个临时位置（即传输到磁盘）。这个类被 [`TemporaryFileUploadHandler`](#django.core.files.uploadhandler.TemporaryFileUploadHandler) 使用。除了 [`UploadedFile`](#django.core.files.uploadedfile.UploadedFile) 的方法外，它还有一个额外的方法：

#### `TemporaryUploadedFile.temporary_file_path()`

返回临时上传文件的完整路径。

#### `class InMemoryUploadedFile`

一个上传到内存中的文件（即传输到内存）。这个类被 [`MemoryFileUploadHandler`](#django.core.files.uploadhandler.MemoryFileUploadHandler) 使用。

## 内置上传处理程序

[`MemoryFileUploadHandler`](#django.core.files.uploadhandler.MemoryFileUploadHandler) 和 [`TemporaryFileUploadHandler`](#django.core.files.uploadhandler.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` 整除，并且大小不能超过 2GB（2<sup>31</sup> 字节）。当有多个处理程序提供的多个分块大小时，Django 将使用任何处理程序定义的最小分块大小。

默认为 64\*2<sup>10</sup> 字节，即 64KB。

#### `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`](#django.core.files.uploadedfile.UploadedFile.content_type_extra)。

这个方法可能会引发一个 `StopFutureHandlers` 异常，以防止后续处理程序处理这个文件。

#### `FileUploadHandler.upload_complete()`

回调信号，表示整个上传（所有文件）已经完成。

#### `FileUploadHandler.upload_interrupted()`

回调信号，表明上传被中断，例如，当用户在文件上传过程中关闭他们的浏览器。

#### `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)` 的元组。
