基于Django+Bootstrap框架,設(shè)計微型小說網(wǎng)站

      網(wǎng)友投稿 1083 2025-04-04

      一、項目背景:


      為了回顧關(guān)于django的文件上傳和分頁功能,打算寫一個微型的小說網(wǎng)站練練手。花了一個下午的時間,寫了個小項目,發(fā)現(xiàn)其中其實遇到了許多問題,不過大部分通過debug之后就解決了,其他部分通過閱讀了Pagination插件以及bootstrap-FileInput插件的官方文檔。

      二、詳細設(shè)計:

      省去小說網(wǎng)站的用戶模塊的功能,小說網(wǎng)站主要的功能就是上傳文件,在線閱讀小說。針對這兩個功能,

      主要用到dajngo內(nèi)置的Pagination模塊,以及選擇一個上傳文件插件即可。因為用的是Bootsrap前端框架,所以就選擇了Bootsrap比較多人用的FileInput插件。

      大致的流程:

      在首頁可以選擇上傳本地的txt文件到服務(wù)器上,然后首頁上同時會異步更新已上傳的txt文本文件列表。

      并且可以在上面選擇閱讀或者刪除的操作。閱讀則跳轉(zhuǎn)到另外一個頁面,后臺會讀取該文本文件,并且進行分頁操作,返回到前端。主要的流程就是這樣。接下來講講Pagination和FileInput插件和核心代碼。

      三、合適的工具:

      django內(nèi)置的Pagination實現(xiàn)分頁功能,這個不用多說,用Django做web開發(fā)分頁功能都會用到。

      bootstrap本身自帶upload file文件上傳插件太丑了,加上功能也不夠完善。所以選擇了Bootstrap FileInput插件。

      版本選擇:

      Python 3.6.6

      Django==2.1.7

      Bootstrap v4.3.1

      bootstrap-fileinput v4.5.2

      四、代碼詳解:

      首先代碼主要分為兩塊,一塊為文件上傳后,接收文件對象,保存到指定的目錄下;第二塊為讀取txt文本文件內(nèi)容,分頁展示到前端頁面。

      首先講講文件上傳的代碼,主要涉及到前端的bootstrap-fileinputt插件。該插件將簡單的HTML文件輸入轉(zhuǎn)換為高級文件選擇器控件。對于不支持JQuery或Javascript的瀏覽器,將有助于回退到正常的HTML文件輸入。

      以上這段是官方的自我介紹,說說我個人感受吧。首先這個插件支持批量上傳,異步上傳等功能,簡化大部分JS邏輯方面的代碼,具體只要跟著官方的API文檔看一看,修改一些參數(shù)即可。其次,對于上傳時會顯示一個進度條,用于顯示上傳的完成度,這樣直觀反映了完成度。

      bootstrap-fileinput的github地址:

      https://github.com/kartik-v/bootstrap-fileinput

      bootstrap-fileinput的官方文檔地址:

      http://plugins.krajee.com/file-input

      bootstrap-fileinput的官方DEMO:

      http://plugins.krajee.com/file-basic-usage-demo

      4.1、文件上傳

      HTML代碼:

      ????

      JS代碼:

      $(document).ready(?function()?{ $("#input-b8").fileinput({????rtl:?true,????uploadUrl:?'/file_receive/',????dropZoneEnabled:?false,????showPreview:?false,????allowedFileExtensions:?['txt'],????initialPreviewConfig:?[] }); });

      代碼說明:

      fileinput()方法里面?zhèn)魅氲氖且粋€json數(shù)據(jù),里面有很多個屬性,每個數(shù)值代表初始化上傳控件時的特性,如果沒有設(shè)置的屬性則按照控件的默認屬性設(shè)置。簡單說下里面幾個屬性的設(shè)置:uploadUrl:上傳文件地址;dropZoneEnabled:是否顯示拖曳區(qū)域;showPreview:是否顯示預(yù)覽區(qū)域;allowedFileExtensions:允許上傳的文件格式。

      后臺代碼

      def?file_receive(request): ????#???接收File-Input空間傳送的文件 ????if?request.method?==?'POST': ????????file?=?request.FILES['input-b8'] ????????file_path?=?"static/books/"+file.name????????with?open(file_path,"wb")?as?f:????????????for?chunk?in?file.chunks(): ????????????????f.write(chunk)????return?JsonResponse({'status':'success'})

      代碼說明:

      以上是后臺接收文件對象并且保存的代碼。我這邊省略判斷上傳文件大小的方法,感興趣的可以在with open()中添加判斷。最后接收文件后,會返回給前端一個json數(shù)據(jù),前端插件接收到返回的JSON數(shù)據(jù)才會確定是否上傳文件成功,bootstrap Fileinput才會先Done狀態(tài)。

      拓展:

      這里有點需要注意的就是,后臺接收上傳的文件,雖然是通過POST的方式上傳,但是不能通過request.POST["filename"]或者request.POST.get("filename","None")兩種方式來訪問。

      而是需要用另外一種方式:

      request.FILES["filename"]或者request.FILES.get("filename","None")

      接下來已經(jīng)得到文件對象,需要把在內(nèi)存中的文件寫入到硬盤中。讀取文件的幾個方法和屬性:

      filename.read():從文件讀取整個上傳的數(shù)據(jù),這個方法只適合小文件

      filename.chunks():按塊返回文件,通過for循環(huán)進行迭代,可以將大文件按塊寫入到服務(wù)器中

      filename.multiple_chunks():當filename文件大于2.5M時,該方法返回True,否則返回False。可以根據(jù)該方法來判斷選擇用1方法還是2方法。

      4.2、異步更新已上傳的文件列表

      HTML代碼:

      ???? ???????? ????????????上傳書籍 ????????????上傳時間 ????????????文件大小 ????????????操作 ???????? ????????{%?for?book?in?objects?%}???????? ????????????{{?book.name}} ????????????{{?book.book_time?}} ????????????{{?book.book_size?}} ????????????閱讀 ????????????刪除 ???????? ????????{%?endfor?%}????

      JS代碼:

      $("#input-b8").on('fileuploaded',function(){????console.log('success'); ????$.get('/book_update/',function(data){????????var?book_html?="\n"?+????????????"上傳書"?+????????????"籍"?+????????????"上傳時間"?+????????????"文件大小"?+????????????"操作"+????????????"";????????console.log(data);????????for?(var?i?in?data){ ????????????book_html?+=?""+?data[i]['name']+""?+????????????????""+data[i]['book_time']+""?+????????????????""+data[i]['book_size']+""?+????????????????"閱讀"+????????????????"刪除"+????????????????"" ????????} ????????$("#book_list").html(book_html)????????console.log(book_html) ????}); });

      代碼說明:

      $("#input-b8").on('fileuploaded',function(){})這個方法時在上傳完文件后進行回調(diào)事件的函數(shù);就是指上傳一個文件成功后就會調(diào)用該方法;所以我將異步更新上傳文件列表的代碼放在這個回調(diào)事件中。當每個文件上傳后,就會請求后臺,查詢指定目錄下的文件列表,生成json格式的數(shù)據(jù)返回前臺,前臺再通過遍歷的形式拿到其中的數(shù)據(jù),進行展示,具體效果如下:

      后臺代碼

      def?book_list(): ????#???獲取books目錄下的書籍 ????file_list?=?[] ????filedir_path?=?"static/books/" ????list_file?=?os.listdir(filedir_path)????for?book?in?list_file: ????????book_info?=?{} ????????book_path?=?filedir_path?+?book ????????book_info['name']?=?book ????????book_info['timestamp']?=?os.path.getctime(book_path) ????????book_info['book_time']?=?time_format(book_info['timestamp']) ????????book_info['book_size']?=?os.path.getsize(book_path) ????????file_list.append(book_info) ????books?=?sorted(file_list,key=?lambda?x:x['timestamp'],reverse=True)????return?books? def?time_format(timestamp): ????#???格式化時間戳成指定的時間 ????time_struct?=?time.localtime(timestamp) ????time_string?=?time.strftime('%Y-%m-%d?%H:%M',time_struct)????return?time_string

      代碼說明:

      代碼其實很簡單,主要是對通過os模塊獲取靜態(tài)目錄static下的books目錄下的文件列表,然后在獲取每個文件的時間戳,通過列表推導(dǎo)式,按時間戳為key值進行逆向排序。

      4.3、文章分頁模塊

      HTML代碼:

      ???? ????????Home ???? ????

      {{?book_name?}}

      ????{%?for?content?in?book_content?%}????{{?content?}} ????{%?endfor?%}
      ???? ????????{%?if?book_content.has_previous??%}???????? ???????????? ????????????????上一頁???????????? ???????? ????????{%?endif?%}????
      ???? ????????
      ????????????第{{?book_content.number?}}頁/共{{?book_content.paginator.num_pages?}}頁????????
      ????
      ????{%?if?book_content.has_next?%}???? ???????? ????????????下一頁???????? ???????? ???????? ???? ????{%?endif?%}

      JS代碼:

      def?book_read(request): ????#???獲取上傳書籍的內(nèi)容 ????if?request.method?==?'GET': ????????book_name?=?request.GET['book_name']????????????#?書籍名稱 ????????file_path?=?"static/books/"?+?book_name?????????#?書籍路徑 ????????with?open(file_path,encoding='gbk',?errors='ignore')?as?f: ????????????book_contents?=?f.readlines() ????????paginator?=?Paginator(book_contents,?50)????????try: ????????????page?=?int(request.GET['page'])??#?頁碼 ????????????book_content?=?paginator.page(page)????????except?Exception?as?e: ????????????book_content?=?paginator.page(1)????????return?render_to_response('book.html',{'book_content':?book_content,?'book_name':?book_name})

      代碼說明:

      讀取文件的所有行,保存在一個列表中(list),每行作為一個元素。然后實例化一個Paginator對象,并且在實例化中傳入一個需要分頁的對象列表,以及一頁包含多少個數(shù)據(jù)。再從接收前端傳送過來的頁碼,取特定頁碼的數(shù)據(jù),再傳回前端。

      拓展:

      1、分頁功能有Django內(nèi)置的Paginator類提供的,該類位于django/core/paginator,需要用的地方導(dǎo)入即可:

      基于Django+Bootstrap框架,設(shè)計微型小說網(wǎng)站

      from django.core.paginator improt Paginator

      2、read()、readline()、readlines()方法的區(qū)別:

      三者都是讀取文件內(nèi)容:

      read([size]):從當前位置其讀取size字節(jié),如果方法里面沒有參數(shù)size,讀取至文件結(jié)束為止。返回的是一個字符串對象。

      readline():方法調(diào)用一次就讀文件一行,該方法返回一個字符串。

      readlines():讀取整個文件所有行,保存在一個列表中,每行作為一個元素

      3、Paginator對象操作: 實例化對象: book_list?=?[1,2,3,4,5,6,7,8] book_content?=?Paginator(book_list,3) 取特定頁的數(shù)據(jù) content?=?book_content.page(2) 查特定頁當前頁碼數(shù): content.number 查分頁后的總頁數(shù) content.num_pages 查詢某一頁是否有上一頁或者查詢上一頁頁碼: content.has_previous() content.previous_page_number() 查詢某一頁是否有下一頁或者查詢下一頁頁碼: content.has_next() content.next_page_number()

      感興趣的同學可以上我GitHub上,項目代碼的地址:

      https://github.com/libuliduobuqiuqiu/noval_test

      -------------------------------

      本文轉(zhuǎn)自李不李多博客51CTO博客

      Django

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔相應(yīng)法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔相應(yīng)法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:PPt背景音樂(ppt背景音樂循環(huán)播放)
      下一篇:excel表編輯公式計算的教程
      相關(guān)文章
      国产亚洲综合久久| 亚洲日韩av无码中文| 色偷偷亚洲男人天堂| 国产成人精品日本亚洲专区6| 亚洲精品美女久久久久| 亚洲午夜久久影院| 亚洲av日韩av激情亚洲| 亚洲AV无码成人网站久久精品大 | 久久亚洲一区二区| 亚洲成A人片在线观看无码不卡| 亚洲欧洲无码AV电影在线观看 | 亚洲1234区乱码| 亚洲乱码在线观看| 亚洲欧美日韩中文字幕一区二区三区| 国内精品久久久久影院亚洲| 亚洲综合成人婷婷五月网址| 亚洲人成电影网站久久| 亚洲乱码日产精品一二三| 亚洲AV香蕉一区区二区三区| 成人亚洲网站www在线观看| 国产在亚洲线视频观看| 精品国产香蕉伊思人在线在线亚洲一区二区 | 亚洲国产福利精品一区二区| 亚洲av片不卡无码久久| 亚洲乱码一区二区三区国产精品| 亚洲另类无码一区二区三区| 婷婷综合缴情亚洲狠狠尤物| 亚洲精品国自产拍在线观看| 国产AⅤ无码专区亚洲AV| 亚洲国产精品VA在线观看麻豆 | 亚洲欧美成人av在线观看| 亚洲а∨天堂久久精品| 久久亚洲精品无码播放| 亚洲av无码成人黄网站在线观看 | 亚洲第一黄片大全| 国产亚洲视频在线播放| 亚洲精品无码AV人在线播放| 亚洲邪恶天堂影院在线观看| 亚洲国产成人久久| 精品亚洲视频在线| 国产亚洲精品不卡在线|