Django基礎(一)

[TOC]css

Django基礎以前戲

HTTP協議(超文本協議)

四大特性

基於TCP/IP之上做用於應用層

基於請求響應

發是請求,給是響應html

無狀態

不保存用戶狀態,連一次就給忘了前端

無鏈接

eg:one night lovepython

數據格式

請求格式

請求首行(請求方式,協議版本等)mysql

請求頭(一大堆K:V鍵值對)jquery

\r\nweb

請求頭(真正的數據 發post請求的時候纔有 若是get請求不會有)sql

響應格式

響應首行數據庫

響應頭django

\r\n

響應體

響應狀態碼

用特定的數字表示一些數據

​ 1xx:服務端已經接收到了你的數據 正在處理 你能夠提交其餘數據

​ 2xx:服務端成功響應(200請求成功)

​ 3xx:重定向

​ 4xx:請求錯誤(404 請求資源不存在 403 拒絕訪問)

​ 5xx:(服務器內部錯誤(500))

請求方式

get請求

​ 朝別人要數據

post請求

​ 向別人提交數據(eg:用戶登陸)

純手擼web框架

  • 手動書寫socket
  • 手動處理http格式數據

簡單c/s鏈接

#服務端
import socket
server = socket.socket()
server.bind(('127.0.0.1', 8081))
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)
    conn.send(b'hello baby')
    conn.close()

稍微複雜web框架

客戶端請求什麼,就返回什麼,eg:客戶端發送http://127.0.0.1:8081/index則服務器返回給客戶端index

import socket
server = socket.socket()
server.bind(('127.0.0.1', 8081))
server.listen(5)
while True:
    conn,addr = server.accept()
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
    data = conn.recv(1024)
    print(data)
    data = data.decode('utf8')
    current_path = data.split('\r\n')[0].split(' ')[1]
    print(current_path)
    if current_path == '/index':
        conn.send(b'index')
        #服務端還能夠打開html文件,將文件中的東西顯示給客戶端
        # with open(r'index.html', 'rb') as f:   
        #     conn.send(f.read())
    else:
        conn.send(b'404 error')
    conn.close()

基於wsgiref

若是我不想寫上面代碼中的socket鏈接和裏面的index等內容,客戶端發送100個不一樣的請求,我也不能手擼100遍啊!那也太累了吧,因此咱們就利用了wsgiref模塊,幫咱們操做起來更簡單和方便,咱們能夠把在wsgiref.py中的必要代碼寫在相對應的文件內,如下是各個文件中要放的東西。

urls.py 路由與視圖函數對象關係 ​ views.py 放的是視圖函數(處理業務邏輯的) ​ templates 模板文件夾(一堆html文件)

wsgiref.py文件

from wsgiref.simple_server import make_server
from urls import urls
from views import *


def run(env,response):
    """
    :param env: 請求相關的全部數據
    :param response: 響應相關的全部數據
    :return:
    """
    response('200 OK',[])
    current_path = env.get('PATH_INFO')  #env裏面有 不少數據,咱們篩選有用的數據就行
    # 先定義一個變量名 用來存儲後續匹配到的函數名
    func = None
    # for循環 匹配後綴
    for url in urls:
        if current_path == url[0]:
            func = url[1]  # 一旦匹配成功 就將匹配到的函數名賦值給func變量
            break  # 主動結束匹配
    # 判斷func是否有值
    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)
    # 實時監聽該地址  只要有客戶端來鏈接 統一交給run函數去處理
    server.serve_forever()  # 啓動服務端,永遠等着客戶端來鏈接

urls.py

from views import *

urls = [
    ('/index',index),  #第二個是函數,若是匹配成功,就去views.py中去找相應的函數去運行
    ('/login',login),
    ('/xxx',xxx),
]

views.py

from urls import urls

def index(env):
    return 'index'


def login(env):
    return 'login'

def error(env):
    return '404 error'


def xxx(env):
    return 'xxx'

客戶端經過訪問服務器獲取字典

咱們這裏須要用到一個模塊jinja2

咱們須要先去下載這個模塊from jinja2 import Template

具體瞭解jinja2請點擊連接https://www.cnblogs.com/yanjiayi098-001/p/11701150.html

wsgiref.py文件

from wsgiref.simple_server import make_server
from urls import urls
from views import *


def run(env,response):
    """
    :param env: 請求相關的全部數據
    :param response: 響應相關的全部數據
    :return:
    """
    response('200 OK',[])
    current_path = env.get('PATH_INFO')  #env裏面有 不少數據,咱們篩選有用的數據就行
    # 先定義一個變量名 用來存儲後續匹配到的函數名
    func = None
    # for循環 匹配後綴
    for url in urls:
        if current_path == url[0]:
            func = url[1]  # 一旦匹配成功 就將匹配到的函數名賦值給func變量
            break  # 主動結束匹配
    # 判斷func是否有值
    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)
    # 實時監聽該地址  只要有客戶端來鏈接 統一交給run函數去處理
    server.serve_forever()  # 啓動服務端,永遠等着客戶端來鏈接

urls.py

urls = [
    ('/get_user',get_user),  #第二個是函數,若是匹配成功,就去views.py中去找相應的函數去運行
    
]

views.py

def get_user(env):
    d = {'name':'jason','pwd':'123','hobby':['read','running','music']}
    with open(r'get_user.html','r',encoding='utf-8') as f:
        data = f.read()
    temp = Template(data)   #將data數據傳給這個temp,作處理
    res = temp.render(user=d)  # 將字典d傳遞給前端頁面 頁面上經過變量名user就可以獲取到該字典
    return res

get_user.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
#jinja2模塊,能夠對字典 進行如下取值,同時這是jinja變量取值 {{ }}的語法
<p>{{ user }}</p>
<p>{{ user.name }}</p>
<p>{{ user['pwd'] }}</p>
<p>{{ user.get('hobby') }}</p>
</body>
</html>

動靜態頁面

靜態頁面:就是一個寫死的頁面

動態頁面:能夠經過更改後端的數據,來反應到瀏覽器的頁面上

​ eg:1.後端獲取當前時間展現到前端

​ 2.後端獲取數據庫中的數據展現到前端

客戶端經過訪問服務器獲取當前時間

那麼若是用戶訪問服務端,則客戶端頁面就會顯示當前時間,這樣該怎麼作呢?

咱們要知道,頁面就是要用到html,若是時間寫在HTML,那麼經過編碼格式,他已經再也不是時間了,那麼怎樣將時間顯示在頁面呢?

作法:咱們要在wsgiref模塊的基礎上,先在html中寫一串特定的字符,在後端將這串html和獲取的時間做交換,具體看代碼

wsgiref.py文件

from wsgiref.simple_server import make_server
from urls import urls
from views import *


def run(env,response):
    """
    :param env: 請求相關的全部數據
    :param response: 響應相關的全部數據
    :return:
    """
    response('200 OK',[])
    current_path = env.get('PATH_INFO')  #env裏面有 不少數據,咱們篩選有用的數據就行
    # 先定義一個變量名 用來存儲後續匹配到的函數名
    func = None
    # for循環 匹配後綴
    for url in urls:
        if current_path == url[0]:
            func = url[1]  # 一旦匹配成功 就將匹配到的函數名賦值給func變量
            break  # 主動結束匹配
    # 判斷func是否有值
    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)
    # 實時監聽該地址  只要有客戶端來鏈接 統一交給run函數去處理
    server.serve_forever()  # 啓動服務端,永遠等着客戶端來鏈接

urls.py

from views import *

urls = [
    ('/get_time',get_time),  #第二個是函數,若是匹配成功,就去views.py中去找相應的函數去運行
    
]

views.py

from urls import *
from datetime import datetime


def get_time():
    current_time = datetime.now().strftime('%Y-%m-%d %X')
    with open(r'get_time.html','r',encoding='utf-8') as f:    #這是一串字符串
        data= f.read()
    data = data.replace('$$time$$',current_time)
    return data

get_time.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
$$time$$
</body>
</html>

客戶端經過訪問服務器獲取數據庫數據

獲取數據庫數據如今就和獲取字典的方法差很少像了,只不過咱們須要建一個數據庫,經過連接數據庫,去數據庫裏面拿值

wsgiref.py文件

from wsgiref.simple_server import make_server
from urls import urls
from views import *


def run(env,response):
    """
    :param env: 請求相關的全部數據
    :param response: 響應相關的全部數據
    :return:
    """
    response('200 OK',[])
    current_path = env.get('PATH_INFO')  #env裏面有 不少數據,咱們篩選有用的數據就行
    # 先定義一個變量名 用來存儲後續匹配到的函數名
    func = None
    # for循環 匹配後綴
    for url in urls:
        if current_path == url[0]:
            func = url[1]  # 一旦匹配成功 就將匹配到的函數名賦值給func變量
            break  # 主動結束匹配
    # 判斷func是否有值
    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)
    # 實時監聽該地址  只要有客戶端來鏈接 統一交給run函數去處理
    server.serve_forever()  # 啓動服務端,永遠等着客戶端來鏈接

urls.py

urls = [
    ('/get_db',get_db),  #第二個是函數,若是匹配成功,就去views.py中去找相應的函數去運行
    
]

views.py

import pymysql

def get_db(env):
    conn = pymysql.connect(
        host = '127.0.0.1',
        port = 3306,
        user = 'root',
        password = 'root',
        database = 'day56',
        charset = 'utf8',
        autocommit = True
    )
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    sql = "select * from userinfo"
    cursor.execute(sql)  #提交sql語句,這個出發的是執行的對象並非一個值
    res = cursor.fetchall()
    print(res)
    with open(r'get_db.html','r',encoding='utf-8') as f:
        data = f.read()
    temp = Template(data)
    ret = temp.render(user_list = res)  # 將字典d傳遞給前端頁面 頁面上經過變量名user就可以獲取到該字典
    return ret

get_db.html

咱們這裏用到了bootstrap搭建頁面,這就是一個典型的動態頁面

<!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.3.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <h1 class="text-center">用戶列表</h1>
            <table class="table table-bordered table-striped table-hover">
                <thead>
                    <tr>
                        <th>id</th>
                        <th>name</th>
                        <th>pwd</th>
                    </tr>
                </thead>
                <tbody>
                    {% for user_dict in user_list %}
                        <tr>
                            <td>{{ user_dict.id }}</td>
                            <td>{{ user_dict.name }}</td>
                            <td>{{ user_dict.pwd }}</td>
                        </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    </div>

</div>
</body>
</html>

python三大主流web框架

​ A:socket部分 ​ B:路由與視圖函數對應關係 ​ C:模板語法

Django Flask Tornado
大而全 自帶的功能特別多 相似於航空母艦<br/> 有時候過於笨重 小而精 自帶的功能特別少 相似於遊騎兵<br/>第三方的模塊特別多,若是將flask第三方模塊所有加起來 徹底能夠超過django<br/>比較依賴於第三方模塊 異步非阻塞<br/> 牛逼到能夠開發遊戲服務器
A用的別人的 wsgiref<br/> B本身寫的<br/> C本身寫的 A用的別人的 werkzeug(基於wsgiref)<br/> B本身寫的<br/> C用的別人的 jinja2 三者全是本身寫的
相關文章
相關標籤/搜索