“Django/docs/2.2.x/ref/files/uploads”的版本间差异
(autoload) |
小 (Page commit) |
||
第1行: | 第1行: | ||
+ | {{DISPLAYTITLE:上传文件和上传处理程序 — Django 文档}} | ||
<div id="module-django.core.files.uploadedfile" class="section"> | <div id="module-django.core.files.uploadedfile" class="section"> | ||
<span id="uploaded-files-and-upload-handlers"></span> | <span id="uploaded-files-and-upload-handlers"></span> | ||
− | = | + | = 上传的文件和上传处理程序 = |
<div id="uploaded-files" class="section"> | <div id="uploaded-files" class="section"> | ||
− | == | + | == 上传的文件 == |
− | ; ''class | + | ; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">UploadedFile</span></span> |
: | : | ||
− | + | 在文件上传过程中,实际文件数据存储在 [[../../request-response#django.http.HttpRequest|request.FILES]] 中。 这本字典中的每个条目都是一个 <code>UploadedFile</code> 对象(或一个子类)——一个上传文件的简单包装器。 您通常会使用以下方法之一来访问上传的内容: | |
− | <code>UploadedFile</code> | ||
− | |||
− | ; < | + | ; <span class="sig-prename descclassname"><span class="pre">UploadedFile.</span></span><span class="sig-name descname"><span class="pre">read</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> |
− | : | + | : 从文件中读取整个上传的数据。 小心使用这种方法:如果上传的文件很大,如果您尝试将其读入内存,它可能会使您的系统不堪重负。 你可能想用 <code>chunks()</code> 代替; 见下文。 |
− | ; < | + | ; <span class="sig-prename descclassname"><span class="pre">UploadedFile.</span></span><span class="sig-name descname"><span class="pre">multiple_chunks</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">chunk_size</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span> |
− | : | + | : 如果上传的文件大到需要读取多个块,则返回 <code>True</code>。 默认情况下,这将是大于 2.5 兆字节的任何文件,但这是可配置的; 见下文。 |
<dl> | <dl> | ||
− | <dt>< | + | <dt><span class="sig-prename descclassname"><span class="pre">UploadedFile.</span></span><span class="sig-name descname"><span class="pre">chunks</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">chunk_size</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span></dt> |
− | <dd><p> | + | <dd><p>返回文件块的生成器。 如果 <code>multiple_chunks()</code> 为 <code>True</code>,则应在循环中使用此方法而不是 <code>read()</code>。</p> |
− | <code>True</code> | + | <p>在实践中,最简单的方法通常是一直使用 <code>chunks()</code>。 循环使用 <code>chunks()</code> 而不是使用 <code>read()</code> 可确保大文件不会占用系统内存。</p></dd></dl> |
− | <p> | ||
− | |||
− | |||
− | + | 以下是 <code>UploadedFile</code> 的一些有用属性: | |
− | ; < | + | ; <span class="sig-prename descclassname"><span class="pre">UploadedFile.</span></span><span class="sig-name descname"><span class="pre">name</span></span> |
− | : | + | : 上传文件的名称(例如 <code>my_file.txt</code>)。 |
− | ; < | + | ; <span class="sig-prename descclassname"><span class="pre">UploadedFile.</span></span><span class="sig-name descname"><span class="pre">size</span></span> |
− | : | + | : 上传文件的大小,以字节为单位。 |
− | ; < | + | ; <span class="sig-prename descclassname"><span class="pre">UploadedFile.</span></span><span class="sig-name descname"><span class="pre">content_type</span></span> |
− | : | + | : 随文件上传的内容类型标头(例如 ''text/plain'' 或 ''application/pdf'')。 与用户提供的任何数据一样,您不应该相信上传的文件实际上是这种类型。 您仍然需要验证文件是否包含内容类型标头声明的内容 - “信任但验证”。 |
− | ; < | + | ; <span class="sig-prename descclassname"><span class="pre">UploadedFile.</span></span><span class="sig-name descname"><span class="pre">content_type_extra</span></span> |
− | : | + | : 包含传递给 <code>content-type</code> 标头的额外参数的字典。 这通常由代表您拦截和处理文件上传的服务(例如 Google App Engine)提供。 因此,您的处理程序可能不会收到上传的文件内容,而是收到文件的 URL 或其他指针。 (参见 [https://www.ietf.org/rfc/rfc2388.txt RFC 2388] 第 5.3 节)。 |
− | ; < | + | ; <span class="sig-prename descclassname"><span class="pre">UploadedFile.</span></span><span class="sig-name descname"><span class="pre">charset</span></span> |
− | : | + | : 对于 ''text/*'' 内容类型,字符集(即 <code>utf8</code>) 由浏览器提供。 同样,“信任但验证”是这里的最佳策略。 |
<div class="admonition note"> | <div class="admonition note"> | ||
− | + | 笔记 | |
− | + | 像普通的 Python 文件一样,你可以通过迭代上传的文件来逐行读取文件: | |
− | |||
<div class="highlight-python notranslate"> | <div class="highlight-python notranslate"> | ||
第57行: | 第52行: | ||
<div class="highlight"> | <div class="highlight"> | ||
− | < | + | <syntaxhighlight lang="python">for line in uploadedfile: |
− | do_something_with(line)</ | + | do_something_with(line)</syntaxhighlight> |
</div> | </div> | ||
</div> | </div> | ||
− | + | 使用 [https://www.python.org/dev/peps/pep-0278 通用换行符] 拆分行。 以下被认为是行尾:Unix 行尾约定 <code>'\n'</code>、Windows 约定 <code>'\r\n'</code> 和旧的 Macintosh 约定 <code>'\r'</code>。 | |
− | |||
− | |||
</div> | </div> | ||
− | + | <code>UploadedFile</code> 的子类包括: | |
− | ; ''class | + | ; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">TemporaryUploadedFile</span></span> |
− | : | + | : 上传到临时位置的文件(即 流到磁盘)。 此类由 [[#django.core.files.uploadhandler.TemporaryFileUploadHandler|TemporaryFileUploadHandler]] 使用。 除了 [[#django.core.files.uploadedfile.UploadedFile|UploadedFile]] 中的方法,它还有一个额外的方法: |
− | ; < | + | ; <span class="sig-prename descclassname"><span class="pre">TemporaryUploadedFile.</span></span><span class="sig-name descname"><span class="pre">temporary_file_path</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> |
− | : | + | : 返回临时上传文件的完整路径。 |
− | ; ''class | + | ; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">InMemoryUploadedFile</span></span> |
− | : | + | : 上传到内存中的文件(即 流到内存)。 此类由 [[#django.core.files.uploadhandler.MemoryFileUploadHandler|MemoryFileUploadHandler]] 使用。 |
第85行: | 第78行: | ||
<span id="built-in-upload-handlers"></span> | <span id="built-in-upload-handlers"></span> | ||
− | == | + | == 内置上传处理程序 == |
− | + | [[#django.core.files.uploadhandler.MemoryFileUploadHandler|MemoryFileUploadHandler]] 和 [[#django.core.files.uploadhandler.TemporaryFileUploadHandler|TemporaryFileUploadHandler]] 一起提供了 Django 的默认文件上传行为,将小文件读入内存,将大文件读入磁盘。 它们位于 <code>django.core.files.uploadhandler</code>。 | |
− | [[#django.core.files.uploadhandler.TemporaryFileUploadHandler| | ||
− | |||
− | |||
− | ; ''class | + | ; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">MemoryFileUploadHandler</span></span> |
: | : | ||
− | + | 文件上传处理程序,将上传的文件以流式传输到内存中(用于小文件)。 | |
− | ; ''class | + | ; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">TemporaryFileUploadHandler</span></span> |
: | : | ||
− | + | 使用 [[#django.core.files.uploadedfile.TemporaryUploadedFile|TemporaryUploadedFile]] 将数据流式传输到临时文件的上传处理程序。 | |
− | [[#django.core.files.uploadedfile.TemporaryUploadedFile| | ||
第108行: | 第97行: | ||
<span id="custom-upload-handlers"></span> | <span id="custom-upload-handlers"></span> | ||
− | == | + | == 编写自定义上传处理程序 == |
− | ; ''class | + | ; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">FileUploadHandler</span></span> |
: | : | ||
− | + | 所有文件上传处理程序都应该是 <code>django.core.files.uploadhandler.FileUploadHandler</code> 的子类。 您可以在任何地方定义上传处理程序。 | |
− | <code>django.core.files.uploadhandler.FileUploadHandler</code> | ||
− | |||
<div id="required-methods" class="section"> | <div id="required-methods" class="section"> | ||
− | === | + | === 必要方法 === |
− | + | 自定义文件上传处理程序 '''必须''' 定义以下方法: | |
<dl> | <dl> | ||
− | <dt>< | + | <dt><span class="sig-prename descclassname"><span class="pre">FileUploadHandler.</span></span><span class="sig-name descname"><span class="pre">receive_data_chunk</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">raw_data</span></span>'', ''<span class="n"><span class="pre">start</span></span>''<span class="sig-paren">)</span></dt> |
− | <dd><p> | + | <dd><p>从文件上传接收数据“块”。</p> |
− | <p><code>raw_data</code> | + | <p><code>raw_data</code> 是包含上传数据的字节串。</p> |
− | <p><code>start</code> | + | <p><code>start</code> 是文件中这个 <code>raw_data</code> 块开始的位置。</p> |
− | + | <p>您返回的数据将被输入到后续上传处理程序的 <code>receive_data_chunk</code> 方法中。 这样,一个处理程序可以成为其他处理程序的“过滤器”。</p> | |
− | <p> | + | <p>从 <code>receive_data_chunk</code> 返回 <code>None</code> 以短路剩余的上传处理程序以获取此块。 如果您自己存储上传的数据并且不希望将来的处理程序存储数据的副本,这将非常有用。</p> |
− | <code>receive_data_chunk</code> | + | <p>如果您引发 <code>StopUpload</code> 或 <code>SkipFile</code> 异常,上传将中止或文件将被完全跳过。</p></dd></dl> |
− | |||
− | <p> | ||
− | |||
− | |||
− | |||
− | <p> | ||
− | |||
<dl> | <dl> | ||
− | <dt>< | + | <dt><span class="sig-prename descclassname"><span class="pre">FileUploadHandler.</span></span><span class="sig-name descname"><span class="pre">file_complete</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">file_size</span></span>''<span class="sig-paren">)</span></dt> |
− | <dd><p> | + | <dd><p>当文件上传完毕时调用。</p> |
− | <p> | + | <p>处理程序应返回一个 <code>UploadedFile</code> 对象,该对象将存储在 <code>request.FILES</code> 中。 处理程序也可能返回 <code>None</code> 以指示 <code>UploadedFile</code> 对象应该来自后续上传处理程序。</p></dd></dl> |
− | |||
− | |||
第150行: | 第128行: | ||
<div id="optional-methods" class="section"> | <div id="optional-methods" class="section"> | ||
− | === | + | === 可选方法 === |
− | + | 自定义上传处理程序也可以定义以下任何一个可选方法或属性: | |
− | |||
<dl> | <dl> | ||
− | <dt>< | + | <dt><span class="sig-prename descclassname"><span class="pre">FileUploadHandler.</span></span><span class="sig-name descname"><span class="pre">chunk_size</span></span></dt> |
− | <dd><p> | + | <dd><p>“块”的大小,以字节为单位,Django 应该存储到内存中并输入处理程序。 也就是说,该属性控制送入 <code>FileUploadHandler.receive_data_chunk</code> 的块的大小。</p> |
− | + | <p>为了获得最佳性能,块大小应可被 <code>4</code> 整除,并且大小不应超过 2 GB(2<sup>31</sup> 字节)。 当多个处理程序提供多个块大小时,Django 将使用任何处理程序定义的最小块大小。</p> | |
− | + | <p>默认为 64*2<sup>10</sup> 字节,或 64 KB。</p></dd></dl> | |
− | <p> | ||
− | |||
− | |||
− | |||
− | <p> | ||
<dl> | <dl> | ||
− | <dt>< | + | <dt><span class="sig-prename descclassname"><span class="pre">FileUploadHandler.</span></span><span class="sig-name descname"><span class="pre">new_file</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">field_name</span></span>'', ''<span class="n"><span class="pre">file_name</span></span>'', ''<span class="n"><span class="pre">content_type</span></span>'', ''<span class="n"><span class="pre">content_length</span></span>'', ''<span class="n"><span class="pre">charset</span></span>'', ''<span class="n"><span class="pre">content_type_extra</span></span>''<span class="sig-paren">)</span></dt> |
− | <dd><p> | + | <dd><p>新文件上传开始的回调信号。 在将任何数据馈送到任何上传处理程序之前调用此方法。</p> |
− | + | <p><code>field_name</code> 是文件 <code><input></code> 字段的字符串名称。</p> | |
− | <p><code>field_name</code> | + | <p><code>file_name</code> 是浏览器提供的文件名。</p> |
− | <p><code>file_name</code> | + | <p><code>content_type</code> 是浏览器提供的 MIME 类型 - 例如 <code>'image/jpeg'</code>。</p> |
− | <p><code>content_type</code> | + | <p><code>content_length</code> 是浏览器给出的图片长度。 有时这不会被提供,而是 <code>None</code>。</p> |
− | <code>'image/jpeg'</code> | + | <p><code>charset</code> 是字符集(即 <code>utf8</code>) 由浏览器给出。 像 <code>content_length</code> 一样,有时不会提供。</p> |
− | <p><code>content_length</code> | + | <p><code>content_type_extra</code> 是来自 <code>content-type</code> 头文件的额外信息。 参见 [[#django.core.files.uploadedfile.UploadedFile.content_type_extra|UploadedFile.content_type_extra]]。</p> |
− | + | <p>此方法可能会引发 <code>StopFutureHandlers</code> 异常以防止将来的处理程序处理此文件。</p></dd></dl> | |
− | <p><code>charset</code> | ||
− | |||
− | <p><code>content_type_extra</code> | ||
− | <code>content-type</code> | ||
− | <p> | ||
− | |||
− | ; < | + | ; <span class="sig-prename descclassname"><span class="pre">FileUploadHandler.</span></span><span class="sig-name descname"><span class="pre">upload_complete</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> |
− | : | + | : 回调信号,表示整个上传(所有文件)已经完成。 |
<dl> | <dl> | ||
− | <dt>< | + | <dt><span class="sig-prename descclassname"><span class="pre">FileUploadHandler.</span></span><span class="sig-name descname"><span class="pre">handle_raw_input</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">input_data</span></span>'', ''<span class="n"><span class="pre">META</span></span>'', ''<span class="n"><span class="pre">content_length</span></span>'', ''<span class="n"><span class="pre">boundary</span></span>'', ''<span class="n"><span class="pre">encoding</span></span>''<span class="sig-paren">)</span></dt> |
− | <dd><p> | + | <dd><p>允许处理程序完全覆盖原始 HTTP 输入的解析。</p> |
− | HTTP | + | <p><code>input_data</code> 是一个类文件对象,支持 <code>read()</code>-ing。</p> |
− | <p><code>input_data</code> | + | <p><code>META</code> 与 <code>request.META</code> 是同一个对象。</p> |
− | <p><code>META</code> | + | <p><code>content_length</code>为<code>input_data</code>中数据的长度。 不要从 <code>input_data</code> 读取超过 <code>content_length</code> 个字节。</p> |
− | <p><code>content_length</code> | + | <p><code>boundary</code> 是此请求的 MIME 边界。</p> |
− | + | <p><code>encoding</code> 是请求的编码。</p> | |
− | <p><code>boundary</code> | + | <p>如果要继续上传处理,则返回 <code>None</code>,如果要直接返回适合请求的新数据结构,则返回 <code>(POST, FILES)</code> 元组。</p></dd></dl> |
− | <p><code>encoding</code> | ||
− | <p> | ||
− | <code>(POST, FILES)</code> | ||
− | |||
第206行: | 第168行: | ||
</div> | </div> | ||
+ | <div class="clearer"> | ||
− | [[Category:Django 2.2.x | + | |
+ | |||
+ | </div> | ||
+ | |||
+ | [[Category:Django 2.2.x 文档]] |
2021年10月31日 (日) 04:05的最新版本
上传的文件和上传处理程序
上传的文件
- 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 第 5.3 节)。
- UploadedFile.charset
- 对于 text/* 内容类型,字符集(即
utf8
) 由浏览器提供。 同样,“信任但验证”是这里的最佳策略。
笔记
像普通的 Python 文件一样,你可以通过迭代上传的文件来逐行读取文件:
使用 通用换行符 拆分行。 以下被认为是行尾: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.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)
元组。