一、引子
1.什麼是web應用?
Web應用程序是一種可以通過Web訪問的應用程序,程序的最大好處是用戶很容易訪問應用程序,用戶只需要有瀏覽器即可,不需要再安裝其他軟件。
2.軟件開發架構
C/S 架構
- 客戶端
- 服務端
B/S架構:本質也是C/S架構
- 瀏覽器
- 服務器
3.HTTP協議
超文本傳輸協議,規定了客戶端與服務端消息傳輸的格式。
四大特性:
- 基於TCP/IP協議作用於應用層的協議
- 基於請求響應
- 無狀態(你我連接千萬次,我仍待你如初識)
- 無連接
數據格式之請求:
- 請求首行
- 請求頭(一堆k,v鍵值對)
- (空格)
- 請求體(post請求攜帶的數據)
數據格式之響應:
- 響應首行
- 響應頭(一堆k,v鍵值對)
- (空格)
- 響應體(你想訪問的數據)
響應狀態碼
- 1XX 服務器已經成功接受到你的數據正在處理,你可以繼續提交其他數據
- 2XX 請求成功 服務器已經將你請求的數據發送給你了
- 3XX 重定向
- 4XX 請求資源不存在
- 5XX 服務器錯誤
二、簡易版本web請求響應
1.找到用戶訪問的頁面路徑
<!--數據格式之請求-->
<!--請求首行-->
GET /index HTTP/1.1/r/n
<!--請求頭-->
Host: 127.0.0.1:8080/r/n
Connection: keep-alive/r/n
Pragma: no-cache/r/n
Cache-Control: no-cache/r/n
Upgrade-Insecure-Requests: 1/r/n
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) 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/r/n
<!--空格-->
/r/n
<!--請求體-->
'
- 將請求bytes轉成字符串(decode)
- 用split方法按/r/n切,取列表的第一個元素,即取到請求首行GET /index HTTP/1.1
- 再按空格切,取第二元素,即得到/index,就是用戶訪問的頁面路徑。
2.基於wsgiref模塊
我們得到用戶訪問的路徑,即可根據用戶的需求返回相應的內容(HTML文件)到用戶瀏覽器。當然我們不必自己造輪子,我們可以基於wsgiref模塊完成上述過程。
from wsgiref.simple_server import make_server
from urls import *
def run(env,response):
"""
:param env: 請求相關的信息
:param response: 響應相關的信息
:return:
"""
print(env) # 是一個大字典 裏面裝了一堆處理好了的鍵值對數據
response('200 OK',[('username','jason'),('password','123')]) # 固定寫法 後面列表裏面一個個元祖會以響應頭kv鍵值對的形式返回給客戶端
# 獲取用戶訪問的路徑
current_path = env.get('PATH_INFO')
if current_path == '/index':
return [b'index']
elif current_path == '/login':
return [b'login']
return [b'hello]
if __name__ == '__main__':
server = make_server('127.0.0.1',8080,run)
server.serve_forever()
3.進階版本
我們在判斷用戶訪問路徑的時候,過多的if判斷會顯得整個代碼冗長累贅,可讀性差,所以我們要拆分代碼。定義一個字典來對應函數功能。
from wsgiref.simple_server import make_server
from urls import *
def index(env):
return 'index'
def login(env):
return 'login'
def error(env):
return '404 error'
urls = {
('/index',index),
('/login',login),
}
def run(env,response):
"""
:param env: 請求相關的信息
:param response: 響應相關的信息
:return:
"""
print(env) # 是一個大字典 裏面裝了一堆處理好了的鍵值對數據
response('200 OK',[('username','jason'),('password','123')]) # 固定寫法 後面列表裏面一個個元祖會以響應頭kv鍵值對的形式返回給客戶端
# 獲取用戶訪問的路徑
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()
最終我們可以將視圖函數歸於一個文件views.py,映射關係歸於另一個文件urls.py。這樣當我們需要增加用戶路徑的時候只需要在urls.py中添一條對應關係,在views.py中定義函數功能即可,實現瞭解耦合操作。我們的HTML文件可以放在一個名爲templates文件夾中。
三、模板渲染
後端生成的數據直接傳遞給前端頁面使用(並且前端頁面可以靈活的操作改數據)
動靜態網頁
靜態網頁:頁面上的數據都是寫死的,萬年不變
動態網頁:頁面上的數據是從後端動態獲取的。比如後端獲取當前時間,後端獲取數據庫數據然後傳遞給前端頁面。
栗子:從後端獲取時間在前端顯示。
# 在views.py文件中
def get_time(env):
# 先獲取當前時間
current_time = time.strftime('%Y-%m-%d %X')
# 打開html文件讀取內容返回給客戶端
with open(r'templates/get_time.html','r',encoding='utf-8') as f:
data = f.read()
# 因爲是以r模式打開的文件,所有獲取到的內容就是一堆字符串,在get_time.html文件中用@@time@@佔位
res = data.replace('@@time@@',current_time) # 字符串的替換
return res
模板語法
依賴於第三方模塊,例如jinja2,jinja2支持前端直接使用類似於python的語法操作數據
<p>{{ user_dic }}</p>
<p>{{ user_dic.name }}</p>
<p>{{ user_dic['name'] }}</p>
<p>{{ user_dic.get('name') }}</p>
<!--for循環語句-->
{% for user in user_dict %} <!--[{},{},{},{}]-->
{% endfor %}
四、web框架?
python三大主流web框架
- Django:大而全,自帶了很多功能模塊,類似於航空母艦 (缺點:有點笨重)
- Flask:短小精悍,自帶的功能模塊特別少,大部分都是依賴於第三方模塊(小而輕)
- Tornado:異步非阻塞 主要用在處理高io 多路複用的情況 可以寫遊戲後端
框架組成部分
- a:socket
- b:路由與視圖函數
- c:模板渲染
Django:
a用的別人的 wsgiref
b自己寫的
c自己寫的
Flask:
a用的別人的 werkzeug
b自己寫的
c用的別人的 jinja2
Tornado:
a,b,c都是自己寫的
五、Django安裝及注意事項
下載方式
1.命令行直接下載
pip3 install django==1.11.11
2.pycharm下載
創建django項目的方式
方式1(命令行創建):
創建django項目
django-admin startproject 項目名
創建app應用
python3 manage.py startapp app01
(首先要切換到項目文件夾,另外注意python3.7只兼容django2.0及以上版本)
啓動django項目
python3 manage.py runserver
ps:用命令行創建django默認不會自動創建templates文件夾
需要你手動自己創建(注意改文件夾路徑是否被添加配置文件中)
方式2(pycharm創建)
創建django項目
FILE >>> new project 選擇第二個django 需要注意名字不能有中文,選擇本地的解釋器,勾選後臺管理
創建app
pycharm命令行創建
python3 manage.py startapp app01
Tools下面run manage task功能欄
啓動點小綠色箭頭
強調:
1.用django一定要保證只有一個在運行狀態 切記切記!!!!!!!
2.一定記得清瀏覽器的緩存
app(應用)的概念
一個django項目就是一所大學,app就是大學裏面的學院
注意新創建的app需要在配置文件中註冊才能生效(*******************)
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config' # 可以用全稱
'app01' # 也可以簡寫
]
django各個文件的作用
應用名
migrations 數據庫遷移記錄相關數據
admin.py django後臺管理相關
models.py 模型表相關
views.py 視圖函數相關
項目名
settings.py 配置文件
urls.py 路由與視圖函數的映射關係
templates
項目用到的所有的html文件
manage.py
django入口文件
六、django小白必會三板斧
from django.shortcuts import render,HttpResponse,redirect
HttpResponse 返回字符串
render 返回一個html頁面
兩種給前端頁面傳值的方式
def reg(request):
user_dict = {'name':'jason','password':'123'}
return render(request,'reg.html',{'user_dict':user_dict})
def reg(request):
user_dict = {'name':'jason','password':'123'}
return render(request,'reg.html',locals())