這篇文章主要介紹了python如何設(shè)計微型小說網(wǎng)站,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
創(chuàng)新互聯(lián)是一家專業(yè)提供遼寧企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站設(shè)計制作、成都做網(wǎng)站、H5高端網(wǎng)站建設(shè)、小程序制作等業(yè)務(wù)。10年已為遼寧眾多企業(yè)、政府機構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站制作公司優(yōu)惠進行中。一、項目背景:
為了回顧關(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代碼:
<div dir=rtl class="file-loading"> <input id="input-b8" name="input-b8" multiple type="file"> </div>
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():當(dāng)filename文件大于2.5M時,該方法返回True,否則返回False??梢愿鶕?jù)該方法來判斷選擇用1方法還是2方法。
4.2、異步更新已上傳的文件列表
HTML代碼:
<div > <table id="book_list" class="table table-striped table-bordered table-hover"> <tr> <th>上傳書籍</th> <th>上傳時間</th> <th>文件大小</th> <th>操作</th> </tr> {% for book in objects %} <tr> <td>{{ book.name}}</td> <td>{{ book.book_time }}</td> <td>{{ book.book_size }}</td> <td><a href="/book_read/?book_name={{ book.name }}" rel="external nofollow" >閱讀</a> <a href="/book_del/?book_name={{ book.name }}" rel="external nofollow" >刪除</a></td> </tr> {% endfor %} </table> </div>
JS代碼:
$("#input-b8").on('fileuploaded',function(){ console.log('success'); $.get('/book_update/',function(data){ var book_html ="<tr>\n" + "<th>上傳書" + "籍</th>" + "<th>上傳時間</th>" + "<th>文件大小</th>" + "<th>操作</th>"+ "</tr>"; console.log(data); for (var i in data){ book_html += "<tr><td>"+ data[i]['name']+"</td>" + "<td>"+data[i]['book_time']+"</td>" + "<td>"+data[i]['book_size']+"</td>" + "<td><a href=\"/book_read/?book_name="+data[i]['name']+"\">閱讀</a>"+ "<a href=\"/book_del/?book_name="+data[i]['name']+"\">刪除</a></td>"+ "</tr>" } $("#book_list").html(book_html) console.log(book_html) }); });
代碼說明:
$("#input-b8").on('fileuploaded',function(){})這個方法時在上傳完文件后進行回調(diào)事件的函數(shù);就是指上傳一個文件成功后就會調(diào)用該方法;所以我將異步更新上傳文件列表的代碼放在這個回調(diào)事件中。當(dāng)每個文件上傳后,就會請求后臺,查詢指定目錄下的文件列表,生成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代碼:
<div class="header text-center "> <a href="/index/" rel="external nofollow" > <i class="fa fa-home fa-2x" aria-hidden="true">Home</i> </a> <h4>{{ book_name }}</h4> </div> <div class="col-md-12 col-sm-offset-1 main"> {% for content in book_content %} <span>{{ content }}</span> {% endfor %} </div> <div class="pagination"> <div class="col-md-4 "> {% if book_content.has_previous %} <i class="fa fa-arrow-left" aria-hidden="true"> <a href="?book_name={{ book_name }}&page={{ book_content.previous_page_number }}" rel="external nofollow" > 上一頁 </a> </i> {% endif %} </div> <div class="col-md-4 "> <h6> 第{{ book_content.number }}頁/共{{ book_content.paginator.num_pages }}頁 </h6> </div> {% if book_content.has_next %} <div class="col-md-4 "> <a href="?book_name={{book_name}}&page={{ book_content.next_page_number }}" rel="external nofollow" > 下一頁 </a> <i class="fa fa-arrow-right" aria-hidden="true"> </i> </div> {% endif %} </div>
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)入即可:
from django.core.paginator improt Paginator
2、read()、readline()、readlines()方法的區(qū)別:
三者都是讀取文件內(nèi)容:
read([size]):從當(dāng)前位置其讀取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)
查特定頁當(dāng)前頁碼數(shù):
content.number
查分頁后的總頁數(shù)
content.num_pages
查詢某一頁是否有上一頁或者查詢上一頁頁碼:
content.has_previous() content.previous_page_number()
查詢某一頁是否有下一頁或者查詢下一頁頁碼:
content.has_next() content.next_page_number()
感謝你能夠認真閱讀完這篇文章,希望小編分享的“python如何設(shè)計微型小說網(wǎng)站”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計公司,關(guān)注創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計公司行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、網(wǎng)站設(shè)計器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。
網(wǎng)站名稱:python如何設(shè)計微型小說網(wǎng)站-創(chuàng)新互聯(lián)
URL分享:http://jinyejixie.com/article4/ccjsie.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營銷型網(wǎng)站建設(shè)、搜索引擎優(yōu)化、網(wǎng)站設(shè)計、做網(wǎng)站、App設(shè)計、移動網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容