File Uploads
Basic file uploads
Handling uploaded files
Where uploaded data is stored
Changing upload handler behavior
UploadedFile objects
Modifying upload handlers on the fly
Writing custom upload handlers

参考: http://docs.djangoproject.com/en/dev/topics/http/file-uploads/

File Uploads

当 Django 处理文件上传时, 文件数据存放在 request.FILES 里面。本文档详 细描述文件时这样保存在磁盘和内存里面的,并且提供定制的方法。

注意: 在文件上传概念上,本文原文没有交代清楚,容易产生很多疑惑。文件上 传在 Django 里处理过程有两部分:首先,上传的文件要放到 request.FILES 里 面(即临时存放地方,可以放到文件系统上,也可以放在内存里,更可以定制 UploadHandler); 第二,视图函数读取 request.FILES 里的数据,处理之(也 是 handler upload file)。

Basic file uploads

一个简单实例:

from django import forms

class UploadFileForm(forms.Form):
    title = forms.CharField(max_length=50)
    file  = forms.FileField()

处理这个表单的视图将接受到存放在 request.FILES 里面的数据。可以通过 request.FILES['file'] 方法访问文件。

注意,只有 request 的 method 时 POST ,并且 <form> 标签里有 'enctype="multipart/form-data"'属性的时候, request.FILES 才有数据。

处理上边表单的视图实例:

from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response

# Imaginary function to handle an uploaded file.
from somewhere import handle_uploaded_file

def upload_file(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            handle_uploaded_file(request.FILES['file'])
            return HttpResponseRedirect('/success/url/')
    else:
        form = UploadFileForm()
    return render_to_response('upload.html', {'form': form})

注意:我们绑定一个表单对象的时候,传递了两个参数 : request.POST , request.FILES 。上面说过,文件数据存放在 request.FILES 里面。

Handling uploaded files

上面的示例很简单,仅仅还有一处细节未曾介绍。那就是 handle_uploaded_file 函数,这是我们自定义的一个函数,用来处理 request.FILES 里的数据。

request.FILES 里面的每个元素都是一个 UploadedFile 对象 — 一个针对 uploaded file 封装的简单 File 子类。下面是它的常用方法和属性:

UploadedFile.read()
一次性读取 uploaded file data 的所有 data 。小心 使用这个函数,对于大文件,一次读取的方式可能会让内存用尽,或者其他危 害。总之,最好使用 chunks() 代替。
UploadedFile.multiple_chunks()
如果 uploaded file 太大(默认大于
  1. 5M,可配置),就认为它需要分块读取,返回 True。
UploadedFile.chunks()
分块读取文件
UploadedFile.name
uploaded file 名字
UploadedFile.size
大小,字节

详细的细节参考: UploadedFile objects

示例中使用的 handle_uploaded_file 函数定义:

def handle_uploaded_file(f):
    destination = open('some/file/name.txt', 'wb+')
    for chunk in f.chunks():
        destination.write(chunk)
    destination.close()

Where uploaded data is stored

Changing upload handler behavior

三个可以改变的设置:

FILE_UPLOAD_MAX_MEMORY_SIZE

大于指定值的 file 被存进文件系统,否则存放在内存。

FILE_UPLOAD_TEMP_DIR

大于指定 FILE_UPLOAD_MAX_MEMORY_SIZE 值的文件存放的文件系统中的路径。

FILE_UPLOAD_PERMISSIONS

上传文件的保存权限

FILE_UPLOAD_HANDLERS

上传文件的操作函数

("django.core.files.uploadhandler.MemoryFileUploadHandler",
 "django.core.files.uploadhandler.TemporaryFileUploadHandler",)

通过定制这个类,可以定制文件上传的细节

UploadedFile objects

class UploadedFile

UploadedFile.content_type

上传文件的 content-type header ,例如 text/plain , application/pdf 。对 于上传的文件,"相信它也要验证"!

UploadedFile.charset

对于 "text/*" 类的 content-types , character 由浏览器设置。

UploadedFile.temporary_file_path()

只有临时保存地是文件系统的文件对象有这个属性,它返回保存的临时路径。

Modifying upload handlers on the fly

定制自己的文件上传操作函数。例如,我们定义有 ProgressBarUploadHandler ,可以这样使用。

request.upload_handlers.insert(0, ProgressBarUploadHandler())

Writing custom upload handlers

定制的 upload handler 须是 django.core.files.uploadhandler.FileUploadHandler 的子类。

REQUEST METHODS

定制的 upload handler 须有下面方法:

FileUploadHandler.receive_data_chunk(self, raw_data, start)
FileUploadHandler.file_complete(self, file_size)

OPTIONAL METHODS

还可以定制这些可选方法或属性:

FileUploadHandler.chunk_size
FileUploadHandler.new_file(self, field_name, file_name, content_type, content_length, charset)
FileUploadHandler.upload_complete(self)
FileUploadHandler.handler_raw_input(self, input_data, META, content_length, boundary, encoding)