title: 利用Django實現(xiàn)一個能與用戶交互的初級框架
author: Sun-Wind
date: September 1, 2021
Django實現(xiàn)基本的框架
- 此框架的功能是搭建服務(wù)器,使得服務(wù)器和客戶端交互
- 此框架可以接受客戶端的請求,并返回根據(jù)請求所得到的結(jié)果
這里列舉一個垃圾識別分類的例子
Django簡介
Django 是一個由 Python 編寫的一個開放源代碼的 Web 應(yīng)用框架。
使用 Django,只要很少的代碼,Python 的程序開發(fā)人員就可以輕松地完成一個正式網(wǎng)站所需要的大部分內(nèi)容,并進一步開發(fā)出全功能的 Web 服務(wù)
MVC模型
Django 本身基于 MVC 模型,即 Model(模型)+ View(視圖)+ Controller(控制器)設(shè)計模式,MVC 模式使后續(xù)對程序的修改和擴展簡化,并且使程序某一部分的重復(fù)利用成為可能。
![](/d/20211017/ccec5bd9e72020931eda06ec6276dec1.gif)
MVT模型
Django 的 MTV 模式本質(zhì)上和 MVC 是一樣的,也是為了各組件間保持松耦合關(guān)系,只是定義上有些許不同,Django 的 MTV 分別是指:
M 表示模型(Model):編寫程序應(yīng)有的功能,負責(zé)業(yè)務(wù)對象與數(shù)據(jù)庫的映射(ORM)。
T 表示模板 (Template):負責(zé)如何把頁面(html)展示給用戶。
V 表示視圖(View):負責(zé)業(yè)務(wù)邏輯,并在適當時候調(diào)用 Model和 Template。
除了以上三層之外,還需要一個 URL 分發(fā)器,它的作用是將一個個 URL 的頁面請求分發(fā)給不同的 View 處理,View 再調(diào)用相應(yīng)的 Model 和 Template,MTV 的響應(yīng)模式如下所示:
簡易圖:
![](/d/20211017/8d5e5eb5ddb3892552b4071951ea9ece.gif)
創(chuàng)建垃圾分類項目
注意:博主使用的是windows系統(tǒng),不同系統(tǒng)使用的指令不一樣
django-admin startproject rub>
使用以上指令創(chuàng)建項目
此時Django會形成一個項目框架,以下會一一解釋說明
- rub:項目的容器
- manage.py:作為一個實用的命令行工具,能夠讓你和項目進行交互
- init.py:此空文件告訴python是一個python包
- asgi.py: ASGI兼容的web服務(wù)器入口,以便運行項目
- settings.py:該項目的配置,比如數(shù)據(jù)庫配置,訪問配置,鏈接配置
- urls.py:該項目的url(路由)聲明
- wsgi.py: WSGI兼容的web服務(wù)器入口,以便運行項目
運行我們的項目
py manage.py runserver 0.0.0.0:8000>
通過以上命令來運行我們的項目
此命令需要在rub文件夾里命名
其中0.0.0.0能夠讓局域網(wǎng)的其他電腦訪問到我們的網(wǎng)站,8000是端口號,也可以改成其他端口號,如果不寫端口號默認是8000
此時命令行會生成對應(yīng)的本地服務(wù)器的http,訪問后如下所示
![](/d/20211017/8c9ce8b7c3540eb5cce46b23083f5d6a.gif)
如果無法訪問,請查看是否是端口占用的問題,可以考慮更換一個端口號
悄悄說一句,8000端口占用多半是酷狗音樂什么的[]( ̄▽ ̄)*
創(chuàng)建app
Django規(guī)定,如果要使用模型層,必須要創(chuàng)建一個app(雖然我們這個項目里面不用,但還是教一下)
django-admin.py startapp app>
然后Django就會自動生成app的框架
py manage.py migrate>
# 創(chuàng)建表結(jié)構(gòu)
py manage.py makemigrations app>
# 讓 Django 知道我們在我們的模型有一些變更
py manage.py migrate app>
# 創(chuàng)建表結(jié)構(gòu)
運行以上指令可以完成數(shù)據(jù)庫表單的創(chuàng)建
這里只是額外引入一下,實際上本項目實現(xiàn)比較簡單,可以無需使用
配置路由
路由簡單的來說就是根據(jù)用戶請求的 URL 鏈接來判斷對應(yīng)的處理程序,并返回處理結(jié)果,也就是 URL 與 Django 的視圖建立映射關(guān)系。
我們在rub的主路由中添加如下配置
path('',include('app.urls')),>
利用include語句可以將app的路由映射進來,這樣我們直接配置app的路由即可
include指的是路由的分發(fā)
Django 項目里多個app目錄共用一個 urls 容易造成混淆,后期維護也不方便。
使用路由分發(fā)(include),讓每個app目錄都單獨擁有自己的 urls。
在app的路由當中加入如下的配置
path('',views.index,name = 'index'),>
path('upload1',views.upload1,name = 'upload1'),>
path方法
Django path() 可以接收四個參數(shù),分別是兩個必選參數(shù):route、view 和兩個可選參數(shù):kwargs、name。
- route:字符串,表示URL規(guī)則,與之匹配的URL會執(zhí)行第二個參數(shù)view
- view:用來執(zhí)行匹配的URL請求
- kwargs:字典參數(shù)(通過此參數(shù)可以實現(xiàn)網(wǎng)頁變量的解析操作,后續(xù)會有解釋)
- name:用來反向獲取URL
視圖層
在app的視圖層中加入如下代碼
def index(request):
return render(request,'app/index.html')
def upload1(request):
myfile = request.FILES.get('pic',None)
if not myfile:
return HttpResponse("沒有上傳的文件信息:")
filename = str(time.time()) + "." + myfile.name.split('.').pop()#這里是對文件名進行預(yù)處理操作,時間函數(shù)可以隨機化一個值,用str方法轉(zhuǎn)換為字符串,然后用split拆分后綴名,可以實現(xiàn)任意圖片形式的保存
destination = open("./static/pic/" + filename,"wb+")#利用open函數(shù)和chunks流寫入static文件夾
for chunk in myfile.chunks(): # 分塊寫入文件
destination.write(chunk)
destination.close()
label = predict_img(path="static/pic/" + filename)#此處是垃圾分類識別函數(shù),因為競賽相關(guān),就不放出具體的識別代碼了,讀者可以參考相關(guān)資料自行補充此函數(shù)
print(label)
os.remove("./static/pic/"+filename)#這里刪除文件,防止用戶傳入文件占用內(nèi)存的問題
context = {}
context['result'] = label # 將result變量對應(yīng)的鍵值設(shè)為lable,這樣可以讓html文件解析lable變量
return render(request,'app/result.html',context)
接下來我們進行逐一解讀
render(): 返回文本,第一個參數(shù)為 request,第二個參數(shù)為字符串(頁面名稱),第三個參數(shù)為字典(可選參數(shù),向頁面?zhèn)鬟f的參數(shù):鍵為頁面參數(shù)名,值為views參數(shù)名)。
簡而言之就是根據(jù)路徑返回我們需要的頁面
注意這里要寫成app/index而不是rub/index,雖然index的網(wǎng)頁文件在rub的templates下創(chuàng)立
Request是一個對象,其屬性簡述如下
- path 請求頁面的全路徑,不包括域名—例如, "/hello/"。m
- ethod 請求中使用的HTTP方法的字符串表示。全大寫表示。如
if request.method == 'GET':
do_something()
elif request.method == 'POST':
do_something_else()
包含所有上傳文件的類字典對象。FILES中的每個Key都是input type="file" name="" />
標簽中name屬性的值. FILES中的每個value 同時也是一個標準Python字典對象,包含下面三個Keys:
filename: 上傳文件名,用Python字符串表示
content-type: 上傳文件的Content type
content: 上傳文件的原始內(nèi)容
注意:只有在請求方法是POST,并且請求頁面中
模板
模板是一個文本,用于分離文檔的表現(xiàn)形式和內(nèi)容
在rub目錄下建立templates文件夾,屆時Django在通過URL尋找時會直接在此文件夾中找到對應(yīng)的網(wǎng)頁文件,在template文件夾下新建一個app文件夾
建立的index.html文件如下
!DOCTYPE html>
html lang="cn">
head>
meta charset="UTF-8">
title>垃圾分類管理/title>
/head>
body>
h2>垃圾分類管理/h2>
{% include 'app/upload.html' %}
/body>
/html>
{% include %} 標簽允許在模板中包含其它的模板的內(nèi)容。
upload.html文件如下:
!DOCTYPE html>
html lang = "en">
head>
meta charset = "UTF-8">
meta name = "viewport" content = "width = device-width,initial-scale=1.0">
title> Document /title>
/head>
body>
h2>文件上傳 /h2>
form action = "{% url 'upload1' %}" method = "post" enctype="multipart/form-data">
{% csrf_token %}
圖片序號:input type = "text" name = "title"/>br/>br/>
請上傳需要識別的圖片:input type = "file" name = "pic"/>br/>br>
input type = "submit" value = "上傳"/>
/form>
/body>
/html>
這里只講解一下csrf
csrf_token 用于form表單中,作用是跨站請求偽造保護。
如果不用{% csrf_token %}標簽,在用 form 表單時,要再次跳轉(zhuǎn)頁面會報403權(quán)限錯誤。
用了{% csrf_token %}標簽,在 form 表單提交數(shù)據(jù)時,才會成功。
至于其他的就是html語言的學(xué)習(xí)了,這里只簡要講解一下
在表單當中,input標簽后面跟對應(yīng)的type屬性,可以上傳相關(guān)的數(shù)據(jù)到后面的name鍵位當中
{% url 'upload1' %}是反方向解析URL,這里會直接將我們輸入的信息提交到uoload1URL當中,然后會激活對應(yīng)的視圖層,也就是說我們提交的圖片最終會傳到upload1函數(shù)中.
我們在上文當中提到的配置path路徑中的name就是這樣的作用,這里圖片上傳的name是'pic'對應(yīng)于我們在上文方法中引用的FILE.get中的參數(shù)
最后一個result界面
html>
div>
p>垃圾分類的結(jié)果是:{{ result }}/p>
/div>
/html>
這里對應(yīng)視圖層當中upload1方法,大家不妨轉(zhuǎn)到視圖層當中再看一下upload1函數(shù)
最后其返回的是render方法,然后返回的是result界面
在這里{{result}}是在html'中定義的一個變量,我們通過render方法可以用lable文本來代替
最后實現(xiàn)的結(jié)果如圖所示
![](/d/20211017/8e04225d87d0b1864c98cf2177008982.gif)
我們只需要上傳圖片,然后提交利用我們自己寫的垃圾分類識別代碼即可得到對應(yīng)的結(jié)果
這里我們提交上我們想要識別的圖片
![](/d/20211017/ba1ed2a8f9020d958830ff836099e307.gif)
結(jié)果
![](/d/20211017/a6054979bfc75f647813be1615ca70ab.gif)
到此這篇關(guān)于Django的基本運用之Django垃圾分類詳解的文章就介紹到這了,更多相關(guān)Django垃圾分類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- Django ORM filter() 的運用詳解
- python 運用Django 開發(fā)后臺接口的實例
- Pycharm 操作Django Model的簡單運用方法