2010-08-15 53 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+')並不是一個好主意。這只是要求目錄遍歷或其他問題。