2010-08-15 46 views
4

我已经用下面的代码成功上传的图片:在django中处理图片上传表单:何时使用save()vs chunks()vs cleaned_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()和cleaned_data。是否有必要遍历块并写入目标文件夹,如文档中的示例一样?我必须使用cleared_data吗?试图找出上传文件的最有效方法,我已经看到了很多不同的方式来做这件事。非常感谢您的帮助。当文件大于settings.FILE_UPLOAD_MAX_MEMORY_SIZE(在Django 1.2默认2.5M)

看看django.core.files.storage.FileSystemStorage类需要

回答

4

组块。它的save()方法为你做了面向块的保存工作,并进行适当的文件锁定。

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

通过直接访问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+')并不是一个好主意。这只是要求目录遍历或其他问题。