我已使用以下代码成功上传了图片:
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()和cleaning_data。是不是必须通过块迭代并写入目标文件夹,如文档中的示例?我必须使用cleaning_data吗?只是想找出最有效的上传文件的方法,我已经看到了很多不同的方法。非常感谢您的帮助。
答案 0 :(得分:4)
当文件大于settings.FILE_UPLOAD_MAX_MEMORY_SIZE
时,需要进行分块(django 1.2中默认为2.5M)
看看django.core.files.storage.FileSystemStorage
课程。它的save()方法为您执行chunk-wise保存作业并执行正确的文件锁定。
storage = FileSystemStorage(
location = '/var/www/site/upfiles',
base_url = '/upfiles'
)
content = request.FILES['the_file']
name = storage.save(None, content) #you can use some suggested name instead of
#None. content.name will be used with None
url = storage.url(name) #<-- get url for the saved file
在旧版本的django中(例如在1.0中),文件名的生成存在缺陷。它不断向文件名添加_
,如果重复上传相同的文件,上传的文件名会越来越长。这似乎在版本1.2中得到修复。
答案 1 :(得分:1)
通过直接访问request.FILES['file']
,您将绕过UploadFileForm正在执行的任何处理(您甚至不需要表单类来处理这样的文件)。 form.cleaned_data['file']
将访问已处理(并清除,如果您添加了干净方法)表单数据。您也可以直接访问request.POST
字典,而不是表单数据。除非您有充分的理由,否则最好使用已清理的表单数据。
在您给出的示例中,还有一个正在使用的模型(正在调用save()方法),它是处理文件访问的模型的字段。如果您想在数据库中保存有关上传文件的信息,那就可以了。
您可以使用内置文件存储API来保存文件:http://docs.djangoproject.com/en/dev/ref/files/storage/#ref-files-storage。
此外,使用用户指定的文件名简单地调用open(MEDIA_ROOT + '/images/'+file.name, 'wb+')
并不是一个好主意。这只是要求目录遍历或其他问题。