在 django 中处理图像上传表单:何时使用 save()、chunks() 和 clean_data?
我已使用以下代码成功上传了图像:
views.py
from django.conf.urls.defaults import *
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response
from django import template
from django.template import RequestContext
from mysite.uploadr.forms import UploadFileForm
def upload_file(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
form.handle_uploaded_file(request.FILES['file'])
return HttpResponse(template.Template('''
<html><head><title>Uploaded</title></head> <body>
<h1>Uploaded</h1>
</body></html>
'''
).render( template.Context({}))
)
else:
form = UploadFileForm()
return render_to_response('upload.html', {'form': form}, context_instance=RequestContext(request))
forms.py
from django import forms
from settings import MEDIA_ROOT
class UploadFileForm(forms.Form):
title = forms.CharField(max_length = 50)
file = forms.FileField()
def handle_uploaded_file(self,file):
#print type(file), "file.name=",file.name
#print dir(file)
destination = open(MEDIA_ROOT + '/images/'+file.name, 'wb+')
for chunk in file.chunks():
destination.write(chunk)
我想更进一步,将图像与正在上传的用户关联起来。我看过一些例子,并且喜欢这篇文章中的技术:https://stackoverflow .com/questions/3348013/django-image-file-uploads。
我注意到他们的代码使用了 save() 和 clean_data。是否不需要像文档中的示例那样迭代块并写入目标文件夹?我必须使用cleaned_data吗?只是想找出最有效的上传文件的方法,我已经看到了很多不同的方法。非常感谢您的帮助。
I have successfully uploaded an image using the following code:
views.py
from django.conf.urls.defaults import *
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response
from django import template
from django.template import RequestContext
from mysite.uploadr.forms import UploadFileForm
def upload_file(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
form.handle_uploaded_file(request.FILES['file'])
return HttpResponse(template.Template('''
<html><head><title>Uploaded</title></head> <body>
<h1>Uploaded</h1>
</body></html>
'''
).render( template.Context({}))
)
else:
form = UploadFileForm()
return render_to_response('upload.html', {'form': form}, context_instance=RequestContext(request))
forms.py
from django import forms
from settings import MEDIA_ROOT
class UploadFileForm(forms.Form):
title = forms.CharField(max_length = 50)
file = forms.FileField()
def handle_uploaded_file(self,file):
#print type(file), "file.name=",file.name
#print dir(file)
destination = open(MEDIA_ROOT + '/images/'+file.name, 'wb+')
for chunk in file.chunks():
destination.write(chunk)
I'd like to go one step further and associate an image with the user who is uploading. I've seen a few examples and have taken a liking to the technique in this post: https://stackoverflow.com/questions/3348013/django-image-file-uploads.
I noticed that their code uses save() and cleaned_data. Is it not necessary to iterate thru the chunks and write to the destination folder like the examples in the documentation? Do I have to use cleaned_data? Just trying to figure out the most efficient means of uploading files, I 've seen so many different ways of doing this. Your help you be greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当文件大于
settings.FILE_UPLOAD_MAX_MEMORY_SIZE
时需要分块(django 1.2 中默认为 2.5M)请查看
django.core.files.storage.FileSystemStorage
类。它的 save() 方法为您执行按块保存的工作并执行正确的文件锁定。在旧版本的 django 中(例如 1.0),文件名的生成存在缺陷。它不断在文件名中添加
_
,并且如果重复上传相同的文件,上传的文件名会变得越来越长。这似乎在 1.2 版本中得到了修复。Chunking is needed when file is bigger than
settings.FILE_UPLOAD_MAX_MEMORY_SIZE
(default 2.5M in django 1.2)Take a look at
django.core.files.storage.FileSystemStorage
class. It's save() method does the chunk-wise saving job for you and does the proper file locking.In the older versions of django (e.g in 1.0) there was a defect in generation of file names. It kept adding
_
to file names and the uploaded file name got longer and longer if you upload the same file repeatedly. This seems to be fixed in version 1.2.通过直接访问 request.FILES['file'],您将绕过 UploadFileForm 正在执行的任何处理(您甚至不需要表单类来处理此类文件)。
form.cleaned_data['file']
将访问已处理(如果添加了 clean 方法,则已清理)的表单数据。您还可以直接访问request.POST
字典,而不是表单数据。除非您有充分的理由,否则最好使用清理后的表单数据。在您提供的示例中,还使用了一个模型(这就是调用 save() 方法的模型),并且该模型的字段正在处理文件访问。如果您想将有关上传文件的信息保存在数据库中,那么就可以这样做。
您可以使用内置文件存储 API 来保存文件: http://docs.djangoproject.com/en/dev/ref/files/storage/#ref-files-storage。
此外,简单地使用用户指定的文件名调用
open(MEDIA_ROOT + '/images/'+file.name, 'wb+')
也不是一个好主意。这只是要求目录遍历或其他问题。By accessing
request.FILES['file']
directly, you're bypassing any processing that your UploadFileForm is doing (you don't even need a form class to handle files like that).form.cleaned_data['file']
would access the processed (and cleaned, if you added a clean method) form data. You could also access therequest.POST
dictionary directly, instead of the form data. Unless you have a good reason to, it's better to use the cleaned form data.In the example you gave, there was also a model being used (which is what the save() method was being called on), and it was the model's field that was handling the file access. If you want to save information about your uploaded files in a database, that's the way to go.
You can use the built-in file storage API for saving files: http://docs.djangoproject.com/en/dev/ref/files/storage/#ref-files-storage.
Also, it's not a good idea to simply call
open(MEDIA_ROOT + '/images/'+file.name, 'wb+')
, with the user-specified file name. That's just asking for directory traversal or other issues.