FileField 在 Django 中不起作用
FileField not working in Django
我正在尝试在我的表单中创建 FileField 并且不在本地保存文件,将文件(作为附件)添加到电子邮件并发送。电子邮件部分代码工作正常,但是当我添加 FileField 时它显示错误“'str' 对象没有属性 'get'”,我正在努力找出问题所在。
查看:
def print(request):
if request.method == 'POST':
form = PrintForm(data=request.POST, request = request)
#print(request.FILES)
if form.is_valid():
contact_name = request.POST.get('contact_name', '')
contact_email = request.POST.get('contact_email', '')
form_content = request.POST.get('content', '')
supervisor = form.cleaned_data['supervisor']
template = get_template('threeD/email/contact_template_for_printing.txt')
context = Context({
'contact_name': contact_name,
'supervisor': supervisor,
'contact_email': contact_email,
'form_content': form_content,
})
content = template.render(context)
subject = "New message"
try:
email = EmailMessage(
subject,
content,
contact_email,
[supervisor],
headers={'Reply-To': contact_email}
)
if request.FILES:
#uploaded_file = request.POST.get('file')
uploaded_file = request.FILES['stl_file'] # file is the name value which you have provided in form for file field
email.attach('uploaded_file.name, uploaded_file.read(), uploaded_file.content_type')
email.send()
except:
return "Attachment error"
messages.success(request, "Thank you for your message.")
return redirect('/index/print/')
else:
form = PrintForm(request=request)
context_dict = {}
context_dict['printers'] = Printer.objects.all()
context_dict['form'] = form
return render(request, 'threeD/print.html', context_dict)
形式:
class PrintForm(forms.Form):
contact_name = forms.CharField(required=True)
contact_email = forms.EmailField(required=True)
supervisor = forms.ChoiceField(
choices=[(str(sup.email), str(sup.name)) for sup in Supervisors.objects.all()]
)
stl_file = forms.FileField(required=False)
stl_file.help_text = "Upload your file as .STL format. If you have more than one file, " \
"make a .zip and upload them all at once"
content = forms.CharField(
required=True,
widget=forms.Textarea
)
def __init__(self, *args, **kwargs):
self.request = kwargs.pop("request")
super(PrintForm, self).__init__(*args, **kwargs)
self.fields['contact_name'].label = "Your name:"
self.fields['stl_file'].label = "Choose your design file:"
这里是 HTML 代码片段,我在这里调用表单:
<div class="panel-body">
<form role="form" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% load bootstrap %}
{{ form|bootstrap }}
<div class="text-center">
<button type="submit" class="btn btn-primary">
<span class="glyphicon glyphicon-send"></span>
Send a message
</button>
</div>
</form>
</div>
环境:
Request Method: POST
Request URL: http://localhost:8000/index/print/
Django Version: 1.9
Python Version: 3.4.3
Installed Applications:
['admin_tools',
'admin_tools.theming',
'admin_tools.menu',
'admin_tools.dashboard',
'threeD.apps.ThreedConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'bootstrapform',
'django.contrib.sites',
'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.facebook']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
这就是我遇到的错误:
Traceback:
File "C:\Python34\lib\site-packages\django-1.9-py3.4.egg\django\core\handlers\base.py" in get_response
235. response = middleware_method(request, response)
File "C:\Python34\lib\site-packages\django-1.9-py3.4.egg\django\middleware\clickjacking.py" in process_response
31. if response.get('X-Frame-Options') is not None:
Exception Type: AttributeError at /index/print/
Exception Value: 'str' object has no attribute 'get'
从视图中删除 try-except 案例后,我得到以下回溯:
回溯:
File "C:\Python34\lib\site-packages\django-1.9-py3.4.egg\django\core\handlers\base.py" in get_response
149. response = self.process_exception_by_middleware(e, request)
File "C:\Python34\lib\site-packages\django-1.9-py3.4.egg\django\core\handlers\base.py" in get_response
147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "E:\Python\Facility\threeD\views.py" in print
145. email.attach('uploaded_file.name, uploaded_file.read(), uploaded_file.content_type')
File "C:\Python34\lib\site-packages\django-1.9-py3.4.egg\django\core\mail\message.py" in attach
307. assert content is not None
Exception Type: AssertionError at /index/print/
Exception Value:
非常感谢任何帮助。谢谢!
您不应使用 request.POST
和 request.FILES
来填充 model/DB。您应该使用表单中的数据。
所以对于文件字段你应该做
uploaded_file = form.cleaned_data['stl_file']
此外,不要这样做,使用来自 form.cleaned_data
的数据
contact_name = request.POST.get('contact_name', '')
宁愿使用
contact_name = form.cleaned_data.get('contact_name', '')
看起来 clickjacking 中间件正在爆炸,因为它读取的响应是一个字符串,而它应该是其他内容。
查看您的代码,这一行可能是罪魁祸首 return "Attachment error"
尝试将其更改为
return HttpResponse('Attachment error')
你可以像这样导入 HttpResponse from django.http import HttpResponse
我正在尝试在我的表单中创建 FileField 并且不在本地保存文件,将文件(作为附件)添加到电子邮件并发送。电子邮件部分代码工作正常,但是当我添加 FileField 时它显示错误“'str' 对象没有属性 'get'”,我正在努力找出问题所在。
查看:
def print(request):
if request.method == 'POST':
form = PrintForm(data=request.POST, request = request)
#print(request.FILES)
if form.is_valid():
contact_name = request.POST.get('contact_name', '')
contact_email = request.POST.get('contact_email', '')
form_content = request.POST.get('content', '')
supervisor = form.cleaned_data['supervisor']
template = get_template('threeD/email/contact_template_for_printing.txt')
context = Context({
'contact_name': contact_name,
'supervisor': supervisor,
'contact_email': contact_email,
'form_content': form_content,
})
content = template.render(context)
subject = "New message"
try:
email = EmailMessage(
subject,
content,
contact_email,
[supervisor],
headers={'Reply-To': contact_email}
)
if request.FILES:
#uploaded_file = request.POST.get('file')
uploaded_file = request.FILES['stl_file'] # file is the name value which you have provided in form for file field
email.attach('uploaded_file.name, uploaded_file.read(), uploaded_file.content_type')
email.send()
except:
return "Attachment error"
messages.success(request, "Thank you for your message.")
return redirect('/index/print/')
else:
form = PrintForm(request=request)
context_dict = {}
context_dict['printers'] = Printer.objects.all()
context_dict['form'] = form
return render(request, 'threeD/print.html', context_dict)
形式:
class PrintForm(forms.Form):
contact_name = forms.CharField(required=True)
contact_email = forms.EmailField(required=True)
supervisor = forms.ChoiceField(
choices=[(str(sup.email), str(sup.name)) for sup in Supervisors.objects.all()]
)
stl_file = forms.FileField(required=False)
stl_file.help_text = "Upload your file as .STL format. If you have more than one file, " \
"make a .zip and upload them all at once"
content = forms.CharField(
required=True,
widget=forms.Textarea
)
def __init__(self, *args, **kwargs):
self.request = kwargs.pop("request")
super(PrintForm, self).__init__(*args, **kwargs)
self.fields['contact_name'].label = "Your name:"
self.fields['stl_file'].label = "Choose your design file:"
这里是 HTML 代码片段,我在这里调用表单:
<div class="panel-body">
<form role="form" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% load bootstrap %}
{{ form|bootstrap }}
<div class="text-center">
<button type="submit" class="btn btn-primary">
<span class="glyphicon glyphicon-send"></span>
Send a message
</button>
</div>
</form>
</div>
环境:
Request Method: POST
Request URL: http://localhost:8000/index/print/
Django Version: 1.9
Python Version: 3.4.3
Installed Applications:
['admin_tools',
'admin_tools.theming',
'admin_tools.menu',
'admin_tools.dashboard',
'threeD.apps.ThreedConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'bootstrapform',
'django.contrib.sites',
'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.facebook']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
这就是我遇到的错误:
Traceback:
File "C:\Python34\lib\site-packages\django-1.9-py3.4.egg\django\core\handlers\base.py" in get_response
235. response = middleware_method(request, response)
File "C:\Python34\lib\site-packages\django-1.9-py3.4.egg\django\middleware\clickjacking.py" in process_response
31. if response.get('X-Frame-Options') is not None:
Exception Type: AttributeError at /index/print/
Exception Value: 'str' object has no attribute 'get'
从视图中删除 try-except 案例后,我得到以下回溯: 回溯:
File "C:\Python34\lib\site-packages\django-1.9-py3.4.egg\django\core\handlers\base.py" in get_response
149. response = self.process_exception_by_middleware(e, request)
File "C:\Python34\lib\site-packages\django-1.9-py3.4.egg\django\core\handlers\base.py" in get_response
147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "E:\Python\Facility\threeD\views.py" in print
145. email.attach('uploaded_file.name, uploaded_file.read(), uploaded_file.content_type')
File "C:\Python34\lib\site-packages\django-1.9-py3.4.egg\django\core\mail\message.py" in attach
307. assert content is not None
Exception Type: AssertionError at /index/print/
Exception Value:
非常感谢任何帮助。谢谢!
您不应使用 request.POST
和 request.FILES
来填充 model/DB。您应该使用表单中的数据。
所以对于文件字段你应该做
uploaded_file = form.cleaned_data['stl_file']
此外,不要这样做,使用来自 form.cleaned_data
contact_name = request.POST.get('contact_name', '')
宁愿使用
contact_name = form.cleaned_data.get('contact_name', '')
看起来 clickjacking 中间件正在爆炸,因为它读取的响应是一个字符串,而它应该是其他内容。
查看您的代码,这一行可能是罪魁祸首 return "Attachment error"
尝试将其更改为
return HttpResponse('Attachment error')
你可以像这样导入 HttpResponse from django.http import HttpResponse