麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

Django文件上傳機(jī)制詳解

2019-11-11 06:21:34
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

文件上傳

    當(dāng)Django處理上傳一個(gè)文件的時(shí)候,文件數(shù)據(jù)被放在request.FILES中。這個(gè)文檔解釋文件怎么樣被存儲(chǔ)在磁盤上或者內(nèi)存中,怎樣定制默認(rèn)的行為。基本文件上傳考慮一個(gè)包含F(xiàn)ileField的簡(jiǎn)單的表單:from  django  import  formsclassUploadFileForm(forms.Form):   title=forms.CharField(max_length=50)   file=forms.FileField()一個(gè)處理這個(gè)表單的視圖將在request.FILES中接受文件數(shù)據(jù) ,request.FILES是一個(gè)字典,它對(duì)每個(gè)FileField(或者是ImageField,或者是其他的FileField的子類)都包含一個(gè)key.所以 從上面的表單中來(lái)的數(shù)據(jù)將可以通過(guò)request.FILES['file']鍵來(lái)訪問(wèn).注意request.FILES只有 在request方法是POST并且發(fā)出POST請(qǐng)求的

有屬性enctype="multipart/form-data".否則,request。FILES將是空的??戳硪粋€(gè)簡(jiǎn)單的;from fdjango.http imPRot HttpResponseRedirectfrom django.shortcuts import render_to_responsefrom somewhere import handle_uploaded_filedef upload_file(request):    if request.method == 'post':        form =  UploadFileForm(rquest.POST,request.FILES)        if form.is_valid():            handle_uploaded_file(request.FILES['file'])            return HttpResponseRedirect('/success/ur/')   else:        form = UploadFileForm()    return render_to_response('upload.html',{'form':form})要注意,我們必須將request.FILES傳遞到表單的構(gòu)造器中;這就是文件數(shù)據(jù)怎樣和表單沾上邊的 。處理上傳的文件最后的難題是怎樣處理從request.FILES中獲得的真實(shí)的文件。這個(gè)字典的每個(gè)輸入都是一個(gè)UploadedFile對(duì)象——一個(gè)上傳之后的文件的簡(jiǎn)單的包裝。你通常會(huì)使用下面的幾個(gè)方法來(lái)訪問(wèn)被上傳的內(nèi)容:UploadedFile.read():從文件中讀取整個(gè)上傳的數(shù)據(jù)。小心整個(gè)方法:如果這個(gè)文件很大,你把它讀到內(nèi)存中會(huì)弄慢你的系統(tǒng)。你可以想要使用chunks()來(lái)代替,看下面;UploadedFile.multiple_chunks():如果上傳的文件足夠大需要分塊就返回真。默認(rèn)的這個(gè)值是2.5兆,當(dāng)然這個(gè)值是可以調(diào)節(jié)的,看下面的UploadedFile.chunks():一個(gè)產(chǎn)生器,返回文件的塊。如果multiple_chunks()是真的話,你應(yīng)該在一個(gè)循環(huán)中使用這個(gè)方法,而不是使用read();UploadedFile.name:上傳文件的名字(比如m_file.txt)UploadedFile.size:以bytes表示的上傳的文件的大小。還有其他的幾個(gè)方法和屬性。你可以自己去查。把他們放在一起,這里是一個(gè)你處理上傳文件的通常方法:def handle_uploaded_file(f):    destination = open('some/file/name.txt','wb+')    for chunk in f.chunks():         destination.write(chunk)    destination.close()在UploadedFile.chunks()上循環(huán)而不是用read()保證大文件不會(huì)大量使用你的系統(tǒng)內(nèi)存。上傳的數(shù)據(jù)存在哪里?在你保存上傳的文件之前,數(shù)據(jù)需要被保存在某些地方。默認(rèn)呢的,如果一個(gè)上傳的文件小于2.5兆,Django會(huì)將上傳的東西放在內(nèi)存里。這意味著只要從內(nèi)存讀取數(shù)據(jù)并保存到硬盤上,所以很快。然而,如果一個(gè)上傳的文件太大,Django將將上傳的文件寫到一個(gè)臨時(shí)的文件中,這個(gè)文件在你的臨時(shí)文件路徑中。在Unix-like的平臺(tái)上意味著你可以預(yù)見(jiàn)Django產(chǎn)生一個(gè)文件保存為/tmp/tmpzfp6I6.upload的文件。如果這個(gè)文件足夠大,你可以觀察到這個(gè)文件的大小在增大。很多細(xì)節(jié)--2.5M;/tmp;等 等 都是簡(jiǎn)單的看上去合理的默認(rèn)值。繼續(xù)閱讀看看你怎么樣個(gè)性化或者完全替代掉上傳行為。改變上傳處理行為三個(gè)設(shè)置改變Django的上傳處理行為:FILE_UPLOAD_MAX_MEMORY_SIZE:以bytes為單位的到內(nèi)存中的最大大小,。比這個(gè)值大的文件將被先存到磁盤上。默認(rèn)是2.5兆FILE_UPLOAD_TEMP_DIR:比FILE_UPLOAD_MAX_MEMORY_SIZE大的文件將被臨時(shí)保存的地方。默認(rèn)是系統(tǒng)標(biāo)準(zhǔn)的臨時(shí)路徑。FILE_UPLOAD_PERMISSIONS:如果這個(gè)沒(méi)有給出或者是None,你將獲得獨(dú)立于系統(tǒng)的行為。大多數(shù)平臺(tái),臨時(shí)文件有一個(gè)0600模式,從內(nèi)存保存的文件將使用系統(tǒng)標(biāo)準(zhǔn)umask。FILE_UPLOAD_HANDLERS:上傳文件的處理器。改變這個(gè)設(shè)置允許完全個(gè)性化——甚至代替——Django的上傳過(guò)程。默認(rèn)是:("django.core.files.uploadhandler.MemoryFileUploadHandler", "django.core.files.uploadhandler.TemporaryFileUploadHandler",)UploadedFile 對(duì)象class UploadedFile作為那些重File繼承的補(bǔ)充,素有的UploadedFile對(duì)象定義了下面的方法和屬性:UploadedFile.content_type文件的content_type頭(比如text/plain orapplication/pdf)。像用戶提供的任何數(shù)據(jù)一樣,你不應(yīng)該信任上傳的數(shù)據(jù)就是這個(gè)類型。你仍然要驗(yàn)證這個(gè)文件包含這個(gè)頭聲明的content-type——“信任但是驗(yàn)證”。UploadedFile.charset對(duì)于text/*的content-types,瀏覽器提供的字符集。再次,“信任但是驗(yàn)證”是最好的策略。UploadedFile.temporary_file_path():只有被傳到磁盤上的文件才有這個(gè)方法,它返回臨時(shí)上傳文件的全路徑。注意: 像通常的Python文件,你可以迭代上傳的文件來(lái)一行一行得讀取文件:for line in uploadedfile:    do_something_with(line)然而,不同于標(biāo)準(zhǔn)Python文件,UploadedFile值懂得/n(也被稱為Unix風(fēng)格)的結(jié)尾。如果你知道你需要處理有不同風(fēng)格結(jié)尾的文件的時(shí)候,你要在你的視圖中作出處理。上傳處理句柄:當(dāng)一個(gè)用戶上傳一個(gè)文件,Django敬愛(ài)那個(gè)這個(gè)文件數(shù)據(jù)傳遞給上傳處理句柄——一個(gè)處理隨著文件上傳處理文件的小類。上傳處理句柄被FILE_UPLOAD_HANDLERS初始化定義,默認(rèn)是:("django.core.files.uploadhandler.MemoryFileUploadHandler", "django.core.files.uploadhandler.TemporaryFileUploadHandler"

,)這兩個(gè)提供了Django處理小文件和大文件的默認(rèn)上產(chǎn)行為。你可以個(gè)性化處理句柄來(lái)個(gè)性化Django處理文件的行為。比如你可以使用個(gè)性化的處理句柄來(lái)強(qiáng)制用戶配額,實(shí)時(shí)地壓縮數(shù)據(jù),渲染進(jìn)度條,甚至在保存在本地的同時(shí)向另一個(gè)存儲(chǔ)地發(fā)送數(shù)據(jù)。實(shí)時(shí)修改上傳處理句柄有的時(shí)候某些視圖要使用不同的上傳行為。這種情況下,你可以重寫一個(gè)上傳處理句柄,通過(guò)request.upload_handlers來(lái)修改。默認(rèn)的,這個(gè)列表包含F(xiàn)ILE_UPLOAD_HANDLERS提供的處理句柄,但是你可以像修改其他列表一樣修改這個(gè)列表。比如,加入你寫了一個(gè)叫做ProgressBarUploadHandler 的處理句柄。你可以通過(guò)下面的形式加到你的上傳處理句柄中:request.upload_handlers.insert(0,ProgressBarUploadHandler())你贏使用list.insert()在這種情況下。因?yàn)檫M(jìn)度條處理句柄需要首先執(zhí)行。記住,處理句柄按照順序執(zhí)行。如果你像完全代替掉上傳處理句柄,你可以賦值一個(gè)新的列表:request.upload_handlers=[ProgressBarUploadHandler()]注意:你只能在訪問(wèn)request.POST或者request.FILES之前修改上傳處理句柄。——如果上傳處理開(kāi)始后再改就沒(méi)用了。如果你在修改reqeust.uplaod_handlers之前訪問(wèn)了request.POST or request.FILES ,Django將拋出一個(gè)錯(cuò)誤。所以,在你的視圖中盡早的修改上傳處理句柄。

寫自定義的上傳處理句柄:

所有的上傳處理句柄都應(yīng) 是 django.core.files.uploadhandler.FileUploadHandler的子類。你可以在任何你需要的地方定義句柄。需要的方法:

自定義的上傳處理句柄必須定義一下的方法:

FileUploadHandler.receive_data_chunk(self,raw_data,start):從文件上傳中接收塊。

raw_data是已經(jīng)上傳的字節(jié)流

start是raw_data塊開(kāi)始的位置

你返回的數(shù)據(jù)將被傳遞到下一個(gè)處理句柄的receive_data_chunk方法中。這樣一個(gè)處理句柄就是另一個(gè)的過(guò)濾器了。

返回None將阻止后面的處理句柄獲得這個(gè)塊,當(dāng)你 自己存儲(chǔ)這個(gè)數(shù)據(jù),而不想其他處理句柄存儲(chǔ)拷貝時(shí)很有用。

如果你觸發(fā)一個(gè)StopUpload或者SkipFile異常,上傳將被放棄或者文件被完全跳過(guò)。

FileUploadHandler.file_complete(self, file_size)

當(dāng) 文件上傳完畢時(shí)調(diào)用。

處理句柄應(yīng)該返回一個(gè)UploadFile對(duì)象,可以存儲(chǔ)在request.FILES中。處理句柄也可以返回None來(lái)使得UploadFile對(duì)象應(yīng)該來(lái)自后來(lái)的上傳處理句柄。

剩下的就是可選的一些方法實(shí)現(xiàn)。

FILE_UPLOAD_MAX_MEMORY_SIZE = 209715200 FILE_UPLOAD_MAX_MEMORY_SIZE = 209715200

在你本機(jī)先好好測(cè)試一下,它是如何占用內(nèi)存,什么時(shí)候開(kāi)始存入temp目錄,怎么遷移到upload目錄底下的

文件上傳的時(shí)候,如果一個(gè)上傳的文件小于2.5兆,Django會(huì)將上傳的東西放在內(nèi)存里,如果上傳的文件大于2.5M,Django將整個(gè)上傳的文件寫到一個(gè)臨時(shí)的文件中,這個(gè)文件在臨時(shí)文件路徑中。上傳完畢后,將調(diào)用View中的_Upload()方法將臨時(shí)文件夾中的臨時(shí)文件分塊寫到上傳文件的存放路徑下,每塊的大小為64K,寫完后臨時(shí)文件將被刪除。

UploadedFile.multiple_chunks():如果上傳的文件足夠大需要分塊就返回真。默認(rèn)的這個(gè)值是2.5兆,當(dāng)然這個(gè)值是可以調(diào)節(jié)的,看下面的UploadedFile.chunks():一個(gè)產(chǎn)生器,返回文件的塊。如果multiple_chunks()是真的話,你應(yīng)該在一個(gè)循環(huán)中使用這個(gè)方法,而不是使用read();

在你保存上傳的文件之前,數(shù)據(jù)需要被保存在某些地方。默認(rèn)呢的,如果一個(gè)上傳的文件小于2.5兆,Django會(huì)將上傳的東西放在內(nèi)存里。這意味著只要從內(nèi)存讀取數(shù)據(jù)并保存到硬盤上,所以很快。然而,如果一個(gè)上傳的文件太大,Django將上傳的文件寫到一個(gè)臨時(shí)的文件中,這個(gè)文件在你的臨時(shí)文件路徑中。在Unix-like的平臺(tái)上意味著你可以預(yù)見(jiàn)Django產(chǎn)生一個(gè)文件保存為/tmp/tmpzfp6I6.upload的文件。如果這個(gè)文件足夠大,你可以觀察到這個(gè)文件的大小在增大。

三個(gè)設(shè)置改變Django的上傳處理行為:FILE_UPLOAD_MAX_MEMORY_SIZE:以bytes為單位的到內(nèi)存中的最大大小,。比這個(gè)值大的文件將被先存到磁盤上。默認(rèn)是2.5兆FILE_UPLOAD_TEMP_DIR:比FILE_UPLOAD_MAX_MEMORY_SIZE大的文件將被臨時(shí)保存的地方。默認(rèn)是系統(tǒng)標(biāo)準(zhǔn)的臨時(shí)路徑。FILE_UPLOAD_PERMISSIONS:如果這個(gè)沒(méi)有給出或者是None,你將獲得獨(dú)立于系統(tǒng)的行為。大多數(shù)平臺(tái),臨時(shí)文件有一個(gè)0600模式,從內(nèi)存保存的文件將使用系統(tǒng)標(biāo)準(zhǔn)umask。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 欧美aaa | 91美女福利视频 | 欧美成人综合视频 | 国产亚洲精品久久午夜玫瑰园 | 成人9禁啪啪无遮挡免费 | 日韩一级成人 | 国内精品久久久久久2021浪潮 | 久久草草亚洲蜜桃臀 | 91在线视频在线观看 | 日本网站在线播放 | 毛片在线播放视频 | 欧美一级淫片免费播放口 | 欧美18—19sex性护士中国 | 精品国产一区二区三区在线观看 | 色播视频网站 | 羞羞色网站 | 国产一精品一av一免费爽爽 | 亚洲一级电影在线观看 | 日本综合久久 | 免费一级特黄毛片 | 在线中文字幕观看 | 久在线播放 | 视频一区二区不卡 | 91国内精品久久久久免费影院 | 免费激情网站 | 久久蜜臀一区二区三区av | 一级精品| 一级一级一级一级毛片 | 免费啪视频在线观看 | 国产99一区二区 | 国产羞羞视频在线观看免费应用 | 视屏一区| 国产一区二区在线免费观看 | 欧美性久久久 | 久久精品亚洲一区 | 国产免费视频在线 | 亚洲成人免费影视 | 亚洲91精品 | 性爱免费视频 | av久草| 中文字幕一二区 |