gpt4 book ai didi

python - Django上传文件的正确访问器

转载 作者:行者123 更新时间:2023-11-28 20:53:14 25 4
gpt4 key购买 nike

假设一个Django形式如下。。。

class MyForm(forms.Form):
attachment = forms.FileField()

我看过许多教程,其中访问上传的Django文件 request.FILES['attachment'],但我的印象是,只要有可能,您应该通过 POST访问 form.cleaned_data['attachment']ed数据。
是否有理由使用 request.FILES[]?这些对象应该包含完全相同的数据吗?

最佳答案

用HTML创建表单时,它具有特定的编码(或将数据发送到服务器的方法)。默认情况下,编码是application/x-www-form-urlencoded,基本上是以单个字符串发送表单详细信息。但是,如果要将文件上载到服务器,则需要将编码设置为multipart/form-data(这是有关此主题的所有教程中都会注意到的enctype="..."行)。这将以多个部分发送数据,每个表单字段一个。关于这两个编码的显示示例,see here
当Django遇到multipart/form-data编码时,它将接收的数据分成两个字典:request.FILES字典包含上载的任何文件,而request.POST包含任何其他表单字段。如果您感兴趣,则处理由MultiPartParser文件中的django/http/__init__.py类完成。
为了演示如何将这些数据显示回代码中,让我们创建一个简单的应用程序。首先,让我们创建一个由字符字段和文件字段组成的简单表单:

from django import forms

class TestForm(forms.Form):
name = forms.CharField()
file = forms.FileField()

接下来,我们将创建一个简单的视图来创建表单,将任何提交的数据绑定到表单,并通过模板呈现它:
from django.shortcuts import render_to_response
from django.template import RequestContext

from forms import TestForm

def show_form(request):
if request.method == 'POST':
form = TestForm(request.POST, request.FILES)
else:
form = TestForm()

context = {
'form': form
}
return render_to_response('show_form.html', context, RequestContext(request))

最后,我们将使用模板显示表单以及有关请求和表单的一些信息:
<html>
<head>
<title>Django forms - file test</title>
</head>

<body>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" />
</form>

<h2>Request details</h2>

<p>
Request method: {{ request.method }}
<br />
POST data: {{ request.POST|default:"No data" }}
<br />
FILES data: {{ request.FILES|default:"No data" }}
</p>

<h2>Form details</h2>

<p>
Cleaned data: {{ form.cleaned_data|default:"No data" }}
</p>

</body>
</html>

请注意,您需要在设置中启用 django.core.context_processors.request上下文处理器才能查看有关请求的详细信息。
如果我们启动服务器并将浏览器指向该视图,就会看到我们期望看到的结果-一个空表单,请求模式为GET,并且没有POST、文件或表单数据。
接下来,在字符字段中输入一个名称,但不要选择要上载的文件。提交时,我们会得到所需文件字段的预期错误。我们更感兴趣的是有关请求的信息:
请求详细信息
请求方式:POST
发布数据:
文件数据:无数据
表单详细信息
清除的数据:无数据
由于浏览器没有发送任何文件信息,Django将所有表单详细信息放入POST字典,并将FILES字典留空。由于表单无效,因此没有与之关联的数据。
现在让我们尝试一下,不需要名字,但是需要上传一个文件:
请求详细信息
请求方式:POST
发布数据:
文件数据: ]>
表单详细信息
清除的数据:无数据
现在,提交的数据已经在POST和FILES字典之间被分割。文件可以通过 request.FILES['file']访问,但不能通过表单清理数据访问,因为表单因缺少名称而无效。由于我上传的文件很小,所以它存储在内存中;超过一定大小(默认为2.5MB)的文件将存储在临时目录中,但您的代码可以处理它们。
最后,让我们使用两个字段的值来尝试:
请求详细信息
请求方式:POST
发布数据:
文件数据: ]>
表单详细信息
清除的数据:{'name':u'Blair','file': }
由于数据有效并绑定到表单,因此也可以通过表单的 cleaned_data访问该文件。
通过 request.FILES访问它有一个潜在的好处:如果表单无效,您仍然可以在要求用户更正数据之前将文件保存在某个地方。这就避免了再次上传文件(如果你处理大文件的话,在时间和带宽方面可能会非常昂贵)。如果您只想处理小文件,这不会有太大的区别,但是使用 request.FILES可能是更好的做法。这也是 Django file upload documentation如何做到的。

关于python - Django上传文件的正确访问器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5384883/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com