【问题标题】:processing an image upload form in django: when to use save() vs chunks() vs cleaned_data?在 django 中处理图像上传表单:何时使用 save() vs chunks() vs clean_data?
【发布时间】:2011-03-29 23:44:39
【问题描述】:

我已使用以下代码成功上传了一张图片:

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吗?只是想找出最有效的上传文件的方法,我已经看到了很多不同的方法。非常感谢您的帮助。

【问题讨论】:

    标签: django django-forms image-uploading image-upload


    【解决方案1】:

    当文件大于settings.FILE_UPLOAD_MAX_MEMORY_SIZE 时需要分块(django 1.2 中默认为 2.5M)

    看看django.core.files.storage.FileSystemStorage 类。它的 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 版中已修复。

    【讨论】:

      【解决方案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+') 也不是一个好主意。那只是询问目录遍历或其他问题。

      【讨论】:

        猜你喜欢
        • 2011-01-17
        • 2020-11-13
        • 1970-01-01
        • 2019-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-14
        相关资源
        最近更新 更多