c/s,b/s架構
c/s:
客戶端 服務端
b/s:
瀏覽器 服務器
超文本傳輸協議
四大特性:
1.基於TCP/IP做用在應用層之上的協議,底層實現仍爲socket
2.基於請求響應:通訊必定是從客戶端開始,服務器端接收到客戶端必定會作出對應響應
3.無狀態:協議不對任何一次通訊狀態和任何數據作保存
4.無鏈接:一次鏈接只完成一次請求-響應,請求-響應完畢後會當即斷開鏈接
1.客戶端與服務端創建鏈接
2.客戶端發生一個http協議指定格式的請求
3.服務器端接收請求後,迴應一個http協議指定格式的響應
4.客戶端將服務器的響應顯示展示給用戶css
數據格式之請求:
請求首行
請求頭(一大堆的k,v鍵值對)
請求體(
GET請求,請求體裏沒有數據.
POST請求中多了Form Data(body中的一種表單請求類型)
因此經過實踐能夠得出GET與POST之間有一個body的「差距」
headers:主要存放cookie等其餘信息
body:主要存放POST的一些數據,如username:xxx
)
數據格式之響應:
響應首行
響應頭(一大堆的k,v鍵值對)
響應體
響應狀態碼:
10X 服務端已經接收你的數據,正在處理,你能夠繼續提交數據
20X 請求成功
30X 重定向
40X 請求錯誤(404:請求資源不存在)(客戶端錯誤狀態碼) 緣由(服務器沒法處理請求)
50X 內部服務器錯誤(服務器錯誤狀態碼) 緣由(服務器處理請求錯誤)
import socket """ 請求首行 b'GET / HTTP/1.1\r\n' 請求頭(一大堆的k,v鍵值對組成) b'Host: 127.0.0.1:8080\r\n' b'Connection: keep-alive\r\n' b'Upgrade-Insecure-Requests: 1\r\n User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 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' 請求體 """ server = socket.socket() server.bind(('127.0.0.1',8080)) server.listen(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) data = data.decode('utf-8') current_path = data.split('\r\n')[0].split(' ')[1] #訪問http://127.0.0.1:8080/index if current_path == '/index': # conn.send(b'<h1>hello baby!</h1>') #打開html發送到前端網頁 with open('01 純手擼版本對應的html頁面.html','rb') as f: conn.send(f.read()) else: conn.send(b'404') conn.close()
from wsgiref.simple_server import make_server from urls import urls from views import * #啓動文件 def run(env,response): print(env) # 是個字典類型 # 固定寫法 response('200 OK',[]) # 列表裏面放的是請求首行的信息,能夠不放,可是必須寫 # 獲取當前用戶訪問路徑 current_path = env.get('PATH_INFO') # 定義一個函數標誌位 func = None for url_list in urls: # urls:[[],[],[]] url_list:['',func] #獲取路由訪問列表 if current_path == url_list[0]: #獲取列表裏相對應的函數方法名稱 func = url_list[1] # 結束for循環了 break if func: #調用函數 res = func(env) else: # 匹配不上 走error res = error(env) return [res.encode('utf-8')] if __name__ == '__main__': server = make_server('127.0.0.1',8888,run) server.serve_forever()
from views import * urls = [ ['/index',index], ['/login',login], ['/reg',reg], ['/get_time',get_time], ['/get_user',get_user], ['/get_db',get_db_info] ]
4.3jinja2(可使用模板語言渲染到頁面),pymysql(鏈接數據庫),函數響應代碼html
from datetime import datetime from jinja2 import Template import pymysql def index(env): with open('templates/index.html','r',encoding='utf-8') as f: data = f.read() return data def login(env): return 'login' def error(env): return '404 error' def reg(env): return 'reg' def get_time(env): ctime = datetime.now().strftime('%Y-%m-%d %X') # 打開文件 with open('templates/get_time.html','r',encoding='utf-8') as f: data = f.read() #在get_time.html的body裏寫一個@@time@@替換成當前事件 res = data.replace('@@time@@',ctime) return res def get_user(env): user = {'name':'jason','age':'18'} with open('templates/get_user.html','r',encoding='utf-8') as f: data = f.read() tmp = Template(data) res = tmp.render(data=user) return res def get_db_info(env): conn = pymysql.connect( host = '127.0.0.1', port = 3306, user = 'root', password = 'admin', database = 'library', charset = 'utf8', autocommit = True ) cursor = conn.cursor(pymysql.cursors.DictCursor) cursor.execute('select * from author_view') user_list = cursor.fetchall() # 打開文件渲染到前端頁面 with open('templates/get_db_user.html','r',encoding='utf-8') as f: data = f.read() tmp = Template(data) res = tmp.render(user_list=user_list) return res 4.3get_db(html文件渲染) <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1"> <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"> <table class="table table-bordered table-hover table-striped"> <thead> <tr> <th>id</th> <th>name</th> <th>age</th> <th>gender</th> <th>nationality</th> </tr> </thead> <tbody> {% for data in user_list %} <tr> <td>{{data.id}}</td> <td>{{data.name}}</td> <td>{{data.age}}</td> <td>{{data.gender}}</td> <td>{{data.nationality}}</td> </tr> {% endfor %} </tbody> </table> </div> </div> </body> </html>
<!--1.用{{後臺傳送過來的變量名(好比data(字典的變量名))}} --> <h1>{{ data }}</h1> <!--1.用{{}}裏用變量名.key就能夠獲取值顯示到前臺頁面 --> <!--1.其餘是不一樣的獲取方法 --> <h1>{{ data.name }}</h1> <h1>{{ data['name'] }}</h1> <h1>{{ data.get('name') }}</h1> <h1>{{ data.age }}</h1> <!--2.相似取python裏的for循環的模板代碼 --> {% for data in user_list %} <tr> <td>{{data.id}}</td> <td>{{data.name}}</td> <td>{{data.age}}</td> <td>{{data.gender}}</td> <td>{{data.nationality}}</td> </tr> {% endfor %}
django(大而全)
flask(小而精)
tornado(異步非阻塞)
a:socket
b:路由與視圖函數
c:模板渲染
django: a用的別人的wsgiref b:本身寫的 c:本身寫的
flask:a用的別人的werkzeug b:本身寫的 c:用的別人的jinja2
tornado:都是本身寫的
注意
1.django版本
2.計算機名不能是中文
3.一個pycharm窗口就一個工程
命令行下載
pip3 install django==1.11.9
命令行建立django項目
django-admin startproject mysite
命令行建立app
#而後到cd到mysite文件夾運行下面命令
# 若是運行命令報錯SyntaxError: Generator expression must be parenthesized
#"C:\python\3.7\lib\site-packages\django\contrib\admin\widgets.py", line 151'%s=%s' % (k, v) for k, v in params.items(),(到widgets.py文件裏刪除times()後面的逗號從新運行就能夠)
python manage.py startapp 應用名
命令行啓動django
python manage.py runserver
用命令行建立的時候,默認沒有templates文件夾,須要你本身手動建立
而且在settings配置文件中寫上路徑
TEMPLATES裏('BACKEND'下面)配置'DIRS': [os.path.join(BASE_DIR, 'templates')]
pycharm下載
點加號 選版本
建立new project選第二個django項目(選本機環境,暫時不要選虛擬環境)
兩種建立app的方式:
python manage.py startapp 應用名
tools下面的run manage.py 可以簡寫並自動提示
在setting裏配置app路徑,在INSTALLED_APPS配置'app01.apps.AaaConfig',
運行方式
python manage.py runserver
pycharm自動啓動
app01
migrate 遷移
migrations 數據庫遷移記錄相關
models.py orm模型類
views.py 視圖函數
templates 放html文件
manage.py django的啓動入口文件
項目名下
setttings.py django項目的配置文件
urls.py 路由與視圖函數的映射關係
#HttpResponse 返回字符串 # render 渲染頁面並返回 # redirect 重定向 from django.shortcuts import render,HttpResponse,redirect # Create your views here. def index(request): #輸出字符串 return HttpResponse('hello django!') def login(request): user = {'name':'jason'} #數據傳輸到頁面顯示 return render(request,'login.html',{'user':user}) def home(request): #重定向到百度 # return redirect('https://www.baidu.com') #重定向到/index return redirect('/index') django默認可以自動重啓,可是速度可能沒有那麼快
data = b'hello world!'
data = str(data,encoding='utf-8')
print(data)
data = bytes(data,encoding='utf-8')
print(data)