django文件上传
Django在處理文件上傳時,文件數(shù)據(jù)被打包封裝在request.FILES中。
一、簡單上傳
首先,寫一個form模型,它必須包含一個FileField:
# forms.py
from django import formsclass UploadFileForm(forms.Form): title = forms.CharField(max_length=50) file = forms.FileField()   處理這個表單的視圖將在request.FILES中收到文件數(shù)據(jù),可以用request.FILES['file']來獲取上傳文件的具體數(shù)據(jù),其中的鍵值‘file’是根據(jù)file = forms.FileField()的變量名來的。
注意:request.FILES只有在請求方法為POST,并且提交請求的<form>具有enctype="multipart/form-data"屬性時才有效。 否則,request.FILES將為空。
下面是一個接收上傳文件的視圖范例:
# views.pyfrom django.http import HttpResponseRedirect
from django.shortcuts import render from .forms import UploadFileForm # 另外寫一個處理上傳過來的文件的方法,并在這里導(dǎo)入 from somewhere import handle_uploaded_file def upload_file(request): if request.method == 'POST': form = UploadFileForm(request.POST, request.FILES) # 注意獲取數(shù)據(jù)的方式 if form.is_valid(): handle_uploaded_file(request.FILES['file']) return HttpResponseRedirect('/success/url/') else: form = UploadFileForm() return render(request, 'upload.html', {'form': form})   請注意,必須將request.FILES傳遞到form的構(gòu)造函數(shù)中。
form = UploadFileForm(request.POST, request.FILES)
下面是一個處理上傳文件的方法的參考例子:
def handle_uploaded_file(f):with open('some/file/name.txt', 'wb+') as destination: for chunk in f.chunks(): destination.write(chunk)   遍歷UploadedFile.chunks(),而不是直接使用read()方法,能確保大文件不會占用系統(tǒng)過多的內(nèi)存。
二、 使用模型處理上傳的文件
如果是通過模型層的model來指定上傳文件的保存方式的話,使用ModelForm更方便。 調(diào)用form.save()的時候,文件對象會保存在相應(yīng)的FileField的upload_to參數(shù)指定的地方。
from django.http import HttpResponseRedirect
from django.shortcuts import render from .forms import ModelFormWithFileField def upload_file(request): if request.method == 'POST': form = ModelFormWithFileField(request.POST, request.FILES) if form.is_valid(): # 這么做就可以了,文件會被保存到Model中upload_to參數(shù)指定的位置 form.save() return HttpResponseRedirect('/success/url/') else: form = ModelFormWithFileField() return render(request, 'upload.html', {'form': form})   如果手動構(gòu)造一個對象,還可以簡單地把文件對象直接從request.FILES賦值給模型:
from django.http import HttpResponseRedirect
from django.shortcuts import render from .forms import UploadFileForm from .models import ModelWithFileField def upload_file(request): if request.method == 'POST': form = UploadFileForm(request.POST, request.FILES) if form.is_valid(): instance = ModelWithFileField(file_field=request.FILES['file']) instance.save() return HttpResponseRedirect('/success/url/') else: form = UploadFileForm() return render(request, 'upload.html', {'form': form})   三、 同時上傳多個文件
如果要使用一個表單字段同時上傳多個文件,需要設(shè)置字段HTML標(biāo)簽的multiple屬性為True,如下所示:
# forms.pyfrom django import formsclass FileFieldForm(forms.Form): file_field = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))   然后,自己編寫一個FormView的子類,并覆蓋它的post方法,來處理多個文件上傳:
# views.py
from django.views.generic.edit import FormView
from .forms import FileFieldForm class FileFieldView(FormView): form_class = FileFieldForm template_name = 'upload.html' # 用你的模版名替換. success_url = '...' # 用你的URL或者reverse()替換. def post(self, request, *args, **kwargs): form_class = self.get_form_class() form = self.get_form(form_class) files = request.FILES.getlist('file_field') if form.is_valid(): for f in files: ... # Do something with each file. return self.form_valid(form) else: return self.form_invalid(form)   四、上傳文件處理器
當(dāng)用戶上傳一個文件的時候,Django會把文件數(shù)據(jù)傳遞給上傳文件處理器–一個類。
上傳處理器的配置定義在FILE_UPLOAD_HANDLERS中,默認(rèn)為:
["django.core.files.uploadhandler.MemoryFileUploadHandler", "django.core.files.uploadhandler.TemporaryFileUploadHandler"]
MemoryFileUploadHandler和TemporaryFileUploadHandler定義了Django的默認(rèn)文件上傳行為:將小文件讀取到內(nèi)存中,大文件放置在磁盤中。
在你保存上傳文件之前,數(shù)據(jù)需要儲存在某個地方。通常,如果上傳文件小于2.5MB,Django會把整個內(nèi)容存到內(nèi)存。 這意味著,文件的保存僅僅涉及到內(nèi)存中的讀取和磁盤的寫入,所以非常快。但是,如果上傳的文件很大,Django會把它寫入一個臨時文件,儲存在你的系統(tǒng)臨時目錄中。在類Unix的平臺下,Django會生成一個文件,名稱類似于/tmp/tmpzfp6I6.upload。
我們可以編寫自定義的處理器,來定制Django如何處理文件。例如,根據(jù)級別不同限制用戶的磁盤配額,在運(yùn)行中壓縮數(shù)據(jù),渲染進(jìn)度條,甚至是轉(zhuǎn)存到另一個儲存位置,而不把它存到本地。
轉(zhuǎn)載于:https://www.cnblogs.com/navysummer/p/10200211.html
總結(jié)
以上是生活随笔為你收集整理的django文件上传的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 赵薇和谢霆锋的十年之约究竟是什么?
 - 下一篇: gui开头的成语有哪些?