Django簡介
一、什么是web應用?
web應用本質上就是一個socket服務端,用戶的瀏覽器就是socket的客戶端。
這樣一來,我們就能實現自己的簡易版web框架了。話不多說,上代碼。
import socket
server = socket.socket()
server.bind(('127.0.0.1', 8080)) # 綁定IP+PORT
server.listen(5) # 同時允許5個等待的連接(半連接池)
while True:
conn, addr = server.accept() # 阻塞,等待客戶端鏈接
data = conn.recv(1024)
conn.send(b'HTTP/1.1 200 OK\r\n\r\n') # 通訊協議
print(data)
# 手動處理http數據獲取用戶訪問的路徑
# http://127.0.0.1:8080/index,訪問時,/index在請求頭的第二位,按如下方式處理
current_path = data.decode('utf-8').split('\r\n')[0].split(' ')[1]
if current_path == '/index':
conn.send(b'index')
else:
conn.send(b'404')
在打印了請求響應后,我們看到了它的輸出如下:
請求首行
b'GET / HTTP/1.1\r\n
請求頭(一大堆kv鍵值對)
Host: 127.0.0.1:8080\r\n
Connection: keep-alive\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8\r\n
\r\n
請求體
可以發現,它的請求頭是HTTP,那么什么是http呢?
二、http協議簡介
在之前的linux網絡系列(戳這里)中,我已經介紹過了,這里再簡單提一下。
http是一種超文本傳輸協議,它規定了客戶端與服務端消息傳輸的格式。
'''
請求的格式:
請求首行
請求頭(一堆k,v鍵值對)
回車,換行符
請求體(post請求攜帶的數據)
響應的格式:
響應首行
響應頭(一堆k,v鍵值對)
回車,換行符
響應體(post請求攜帶的數據)
'''
http的四大特性:
"""
1、基于TCP/IP協議作用于應用層的協議
2、基于請求響應
3、無狀態
4、無連接
"""
'''
無狀態是指協議對于事務處理沒有記憶能力,服務器不知道客戶端是什么狀態。即我們給服務器發送 HTTP 請求之后,服務器根據請求,
會給我們發送數據過來,但是,發送完,不會記錄任何信息。
無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,并收到客戶的應答后,即斷開連接。
'''
響應狀態碼:
"""
1xx 服務器已經成功接收到你的數據正在處理,你可以繼續提交其他數據
2xx 請求成功,服務器已經將你請求的數據發送給你了
3xx 重定向
4xx 請求資源不存在
5xx 服務器錯誤
"""
三、動靜態網頁
之前linux網絡那篇博客已經介紹過(詳情戳這里),這里再次提一嘴:
靜態網頁:
頁面上的數據都是寫死的,萬年不變
動態網頁:
頁面上的數據是從后端動態獲取的(比如后端獲取當前時間;后端獲取數據庫數據然后傳遞給前端頁面)
四、模板渲染
后端生成的數據直接傳遞給前端頁面使用(并且前端頁面可以靈活的操作數據),這就用到了模板語法。
模板渲染,模板語法需要依賴于第三方模塊,安裝如下:
pip3 install jinja2
模板語法: jinja2支持前端直接使用類似于python的語法操作數據
可以從數據庫中查詢數據,然后去替換html中的對應內容,再發送給瀏覽器完成渲染。 這個過程就相當于HTML模板渲染數據。 本質上就是HTML內容中利用一些特殊的符號來替換要展示的數據。jinja2就可以實現模板渲染。
到了這里,我們就要自定義一個框架,展示動態的網頁了。
五、自定義web框架
除了使用jinja2來把數據處理前端數據外,我們還要用到一個wsgiref模塊,來替換我們自己寫的web框架的socket server部分。
WSGI(Web Server Common Interface)是專門為Python語言制定的web服務器與應用程序之間的網關接口規范。常用的WSGI服務器有uwsgi、Gunicorn。而Python標準庫提供的獨立WSGI服務器叫wsgiref,Django開發環境用的就是這個模塊來做服務器。
wsgiref是官方給出的一個實現了WSGI標準用于演示用的簡單Python內置庫,它實現了一個簡單的WSGI Server和WSGI Application(在simple_server模塊中),主要分為五個模塊:simple_server, util, headers, handlers, validate。
為了實現簡易web框架,我們需要建立三個文件
main.py:主邏輯
urls.py:專門存放視圖函數的對應關系
views.py:專門存放視圖函數
還需要一個templates文件夾,專門放前端頁面。
main.py:
from wsgiref.simple_server import make_server
from urls import *
def run(env, response):
'''
:param env: 請求相關的信息
:param response: 響應相關的信息
:return:
'''
print(env) # 是一個大字典 里面裝了一堆處理好了的鍵值對數據
# 固定寫法 后面列表里面一個個元組會以響應頭kv鍵值對的形式返回給客戶端
response('200 OK', [('username','shj'),('password','123')])
# 獲取用戶訪問的路徑,env是一個大字典,PATH_INFO鍵對應的值就是用戶訪問的路徑
current_path = env.get('PATH_INFO')
# 定義一個存儲函數名的變量
func = None
# 循環比對路由與視圖函數的映射關系
for url_map in urls: # url_map=('/index', index)
if current_path == url_map[0]:
func = url_map[1]
# 只要匹配成功,直接結束循環
break
if func:
res = func(env)
else:
res = error(env)
return [res.encode('utf-8')] # 統一在這里對結果進行編碼處理
if __name__ == '__main__':
server = make_server('127.0.0.1',8080,run)
server.serve_forever()
urls.py:
from views import *
urls = [
('/index', index),
('/login', login),
('/reg', reg),
('/get_time', get_time),
('/get_user', get_user),
('/get_db', get_db),
]
views.py:
import time
import pymysql
from jinja2 import Template
# 此文件專門用來存放視圖函數
def index(env):
return 'index'
def login(env):
return 'login'
def reg(env):
return 'reg'
def get_time(env):
current_time = time.strftime('%Y-%m-%d %X')
# 打開html文件讀取內容返回給客戶端
with open('templates/get_time.html', 'r', encoding='utf-8') as f:
data = f.read()
# r模式打開的,read的結果是字符串
res = data.replace('@@time@@', current_time)
return res
'''自己手寫數據,交給前端渲染'''
def get_user(env):
with open('templates/get_user.html', 'r', encoding='utf-8') as f:
data = f.read()
tmp = Template(data) # 生成模板文件
# 將字典傳遞給前端頁面 前端通過變量名user_dic就可以獲取到該字典
return tmp.render(user_dic={'name':'shj','password':'123'}) # 把數據填充到模板里面并返回
'''從數據庫查詢數據,交給前端頁面渲染'''
def get_db(env):
# 連接數據庫,獲取數據,渲染到前端頁面
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='123456',
database='test',
charset='utf8',
autocommit=True
)
cursor = conn.cursor(pymysql.cursors.DictCursor)
cursor.execute('select * from user_info')
user_dic = cursor.fetchall() # [{},{},]
with open('templates/get_db.html', 'r', encoding='utf-8') as f:
data = f.read()
tmp = Template(data) # 生成模板文件
return tmp.render(user_dic=user_dic) # 把數據填充到模板里面并返回
def error(env):
return '404 error'
get_db.html:(模板語法)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<table class="table table-striped table-hover table-bordered">
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>password</th>
</tr>
</thead>
<tbody>
{% for user in user_dic %}
<tr>
<td>{{user.id}}</td>
<td>{{user.name}}</td>
<td>{{user.password}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
get_user.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<p>{{user_dic}}</p>
<p>{{user_dic.name}}</p>
<p>{{user_dic['password']}}</p>
<p>{{user_dic.get('name')}}</p>
</body>
</html>
get_time.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
@@time@@
</body>
</html>
根據上面的代碼,我們通過一張簡易的請求流程圖來總結一下
六、Django框架
6.1、什么是web框架呢?
Web應用框架(Web application framework)是一種開發框架,用來支持動態網站、網絡應用程序及網絡服務的開發。其類型有基于請求的和基于組件的兩種框架。
Web應用框架有助于減輕網頁開發時共通性活動的工作負荷,例如許多框架提供數據庫訪問接口、標準樣板以及會話管理等,可提升代碼的可再用性。
6.2、python三大主流框架
- Django:大而全。自帶了很多功能模塊,但是有點笨重
- Flask:短小精悍,自帶的功能模塊特別少,大部分都是依賴于第三方模塊(小而精)
- Tornado:異步非阻塞。主要用在處理高IO,多路復用的情況,可以寫游戲后端
web框架的三個部分:
a:socket
b:路由與視圖函數
c:模板渲染
Django:
a用的別人的(wsgiref)
b、c是自己寫的
Flask:
a用的別人的(werkzeug)
b是自己寫的
c用的別人的(jinja2)
Tornado:
a、b、c都是自己寫的
6.3、使用Django創建項目的注意事項
- 計算機的名稱不能有中文
- 一個pycharm窗口就是一個項目,不要多個項目放在一個窗口里面
- 項目名不能起中文
6.4、下載
//下載
pip3 install django==1.11.11
//驗證是否下載成功
django-admin
6.5、創建Django項目的方式
方式一(命令行創建):
創建Django項目: django-admin startproject 項目名
創建app應用: python3 manage.py startapp app01(我一般以app+編號命名)
啟動django項目: python3 manage.py runserver
注意:
1、用命令行創建django默認不會自動創建templates文件夾,需要手動創建
2、去檢查settings配置文件,是否加入了路徑配置
方式二(pycharm創建):
FILE >>> new project 選擇第二個django 需要注意名字不能有中文,選擇本地的解釋器,勾選后臺管理
創建app
第一種:pycharm命令行創建:python36 manage.py startapp app01
第二種:Tools下面run manage task功能欄,然后輸入:start app02
啟動點小綠色箭頭需要強調的是:
1、用django一定要保證只有一個在運行狀態
2、一定記得清理瀏覽器的緩存
6.6、一些概念
app的概念:一個django項目就是一所大學,app就是大學里面的學院。
注意新創建的app需要在配置文件中注冊才能生效
注冊方式:
找到配置文件的INSTALLED_APPS
然后在后面追加,如下,既可以寫全稱,也可以簡寫
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config', # 可以用全稱
'app01' # 也可以簡寫
]
6.7、django各個文件的作用
6.8、django必會三板斧
from django.shortcuts import HttpResponse, render, redirect
1、 HttpResponse:內部傳入一個字符串參數,返回給瀏覽器。
例如:
def index(request): # 業務邏輯代碼 return HttpResponse("OK")
2、render:除request參數外還接受一個待渲染的模板文件和一個保存具體數據的字典參數。
將數據填充進模板文件,最后把結果返回給瀏覽器。(類似于我們上面用到的jinja2)
兩種給前端頁面傳值的方式:
'''第一種''' def reg(request): user_dict = {'name':'shj','password':'123'} return render(request,'reg.html',{'user_dict':user_dict}) # templates自動去找html文件 '''第二種''' def reg(request): user_dict = {'name':'shj','password':'123'} return render(request,'reg.html',locals()) # locals()會把作用域內所有變量傳到前端,雖然方便,但一定慎用
模板語言: 渲染變量:{{ }} 渲染標簽: {% %}
3、redirect:重定向------接收一個URL參數,跳轉到指定的URL。
def login(request): return redirect('http://www.xiaohuar.com')
智能推薦
Django簡介和安裝
目錄 Django MVC模型 Django的MTV模型 Django的安裝 虛擬環境 Django Django是一個開放源代碼的Web應用框架,由Python寫成,其網站的特點是高質量,可維護,可擴展,Django的web項目可在短時間內完成。 MVC模型 Django是一個基于MVC構造的框架,即模型M,視圖V 和 控制器C。它是一種軟件設計典范,用一種業務邏輯、數據、界面顯示分離...
Django簡介和配置
Django的架構思想 Model 數據庫 Template 模板文件 View 業務處理 下載django: pip3 install django 創建一個Django工程 django-ad...
Django----簡介
Django ---- 簡介 Django發布于2005年,是當前Python世界里最負盛名且成熟的網絡框架。最初用來制作在線新聞的Web站點。 Django是一個用Python編寫的開放源代碼的Web應用框架(源代碼是開源的,遵守BSD版權)。采用了MVC的框架模式,也有很多人把它稱為MVT(MTV)模式。 MVC 設計模式 一種軟件設計典范,用一種業務邏輯,使數據,界面顯示分離的方法組織代碼,...
Django框架簡介
框架(framework),指為解決一個開放性的問題而設計的具有一 定約束性的支撐結構,使用框架可以幫助你快速開發特定的系統。 部署Django環境 下載安裝Django模塊 方法一:使用pip工具 更新pip的版本 首先要確保安裝了pip工具 方法二:使用git 方法三:下載Django的py包,然后使用python命令安裝 檢測是否安裝成功 安裝數據庫 django默認提供了Sqlite數據庫...
Django簡介(下)
Django簡單應用 模型的增刪改查(ORM模塊) 數據的查詢 查詢所有數據 按照指定條件查詢 計數語句 符合條件的多條數據查詢 模糊查詢 數據的增加 第一種方式: 第二種方式(重點) 關于數據庫表名的設計 關于模型與數據庫數據的關系 視圖與模型的結合使用 設計顯示用戶的操作頁面 HTML操作頁面 模型的增刪改查(ORM模塊) 數據的查詢 查詢所有數據 導包 格式:模型類名.objects.all...
猜你喜歡
django命令簡介
django命令目錄: 在cmd中輸入:dango-admin即可返回全部的django的命令 引入 Windows+R,輸入cmd,然后在命令行輸入即可返回django的全部命令: 命令代碼解釋 check:檢測所有項目是否存在問題 compilemessages:編譯語言文件,用于項目區域語言設置 dbshell:進度django配置的數據庫,可執行sql語句 diffsetti...
Django簡介及安裝
Djano簡介 基本介紹 Django是一個由python編寫的一個開放源代碼的web應用框架 Dajngo的模型是MVC模型:即 Model(模型)+ View(視圖)+ Controlle(控制器) MVC的優勢:低耦合,開發快捷,部署方便,可重用性高 ,維護成本低 特點 強大的數據庫功能 自帶強大的后臺功能 優雅的網址 MVC與MTV模型 MVC模式 是軟件工程的一種軟件架構模式,把軟件系統...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...