第七十四篇 web應用本質與django基礎

1、web應用的本質

1.回顧

1.socket網絡編程:html

1.架構:C/S架構
2.協議:TCP/UDP協議
3.\TCP/UDP協議屬於OSI七層協議中的傳輸層

2.web應用:python

1.架構:B/S架構
2.協議:HTTP協議
3.HTTP協議屬於OSI七層協議中的應用層
4.OSI七層協議從上到下分別是:7)應用層、6)表示層、5)會話層、4)傳輸層、3)網絡層、2)數據鏈路層、1)物理層。其中高層(七、六、五、4)定義了應用程序的功能,下三層(三、二、1)主要面向經過網絡的端到端的數據流
5.應用層:HTTP、FTP等,對應應用程序的通訊服務。表示層:加密、ASCII碼,定義數據格式以及加密。會話層:SQL、rpc,控制會話。傳輸層:TCP、UDP,數據流複用和數據包排序。網絡層:IP、IPX,定義全部結點的邏輯地址。數據鏈路層:mac地址。物理層:傳輸介質。

3.補充:mysql

# 字符串轉字節:
bytes('字符串', encoding='utf-8')

# 字節轉字符串
str(b"字節", encoding='utf-8')

2.web框架的本質

1.基於B/S架構以及Http協議實現客戶端與服務端交互的應用程序web

2.客戶端就是用戶的瀏覽器,用於發送HTTP請求和接收服務器發來的HTTP響應sql

3.服務端就是socket服務端,用於接收客戶端發來的HTTP請求和發送HTTP響應數據庫

2、自定義一個web框架

1.目標:將自定製的server變成一個動態的serverdjango

2.HTTP請求和HTTP響應通常都包含兩個部分,第一個部分是頭,第二個部分是體編程

3.請求頭通常包含了請求的頁面連接,那麼服務端經過比對以後,若是有該頁面,會返回狀態碼和頁面內容flask

1.HTTP協議

1.簡單的請求-響應協議,一般運行在TCP之上。它指定了客戶端可能發送給服務器什麼樣的消息以及獲得什麼樣的響應

2.HTTP是基於客戶端/服務器模式,且面向鏈接,典型的HTTP事務處理:1)客戶端與服務器創建鏈接;2)客戶端向服務器提出請求;3)服務器接受請求,並根據請求返回響應的文件做爲應答;4)客戶端與服務器關閉鏈接

3.HTTP請求頭的內容或屬性:

GET / HTTP/1.1   # 1.請求方式 根路由(連在IP地址後的網頁連接) HTTP協議的版本

Host: 127.0.0.1:8080   2.IP地址(包含端口)

Connection: keep-alive  3.連接狀態:保持激活

Cache-Control: max-age=0  4.緩存控制

Upgrade-Insecure-Requests: 1  5.升級加密請求
 
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36   6.用戶代理(瀏覽器幫用戶去請求服務端的代理,裏面是瀏覽器內核)
                Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3    7.接收的文件類型
                
Accept-Encoding: gzip, deflate, br   8.接收的編碼
Accept-Language: zh-CN,zh;q=0.9    9.接收的語言

4.請求頭中分行使用\r\n來寫的,而兩個\r\n表示請求頭結束,後面的是請求體,也就是請求內容

5.服務端發送的響應頭通常會帶有HTTP協議版本號、HTTP狀態碼,也是用兩個\r\n來將響應頭和響應體隔開

http/1.1 200 ok \r\n\r\n hello world

2.動態的server

1.以socket服務端爲基礎,經過路由系統來實現動態服務端

2.路由系統是經過將客戶端請求的url映射到相對應的函數上,最後執行函數來實現的

3.實例:

# socket服務器
def run():
    import socket

    server = socket.socket()
    server.bind(('127.0.0.1', 8000))
    server.listen()  # 半鏈接池,有默認參數,選填

    while True:
        conn, addr = server.accept()
        data = conn.recv(1024)  

        # print(data, type(data))
        data_str = str(data, encoding='utf-8')

        header_list = data_str.split('\r\n\r\n')

        headers = header_list[0]
        url = headers.split('\r\n')[0].split(' ')[1]

        # 直接在源碼上修改不太適合實際開發,可拓展性差
        # if url == "/index":
            # res = bytes("index", encoding='utf-8')
        # else:
            # res = bytes('404 NO FOUND', encoding='utf-8')

        # 遍歷路由系統,判斷以後取出對應的函數
        func_name = None
        for items in routes:
            if items[0] == url:
                func_name = items[1]
                break

        # 判斷路由系統映射的函數是否存在,存在則返回相應的內容
        if func_name:
            res = func_name()
        else:
            res = bytes('404 NO FOUND', encoding='utf-8')

        conn.send(bytes("GET HTTP/1.1 200 OK\r\n\r\n", encoding='utf-8'))
        conn.send(res)
        conn.close()
        
# 路由系統:將客戶端請求的url映射到相對應的函數,最後執行函數
# 裝着路由映射關係的容器(裝元組的列表)
routes = [
    ("/index", index),
    ("/login", login),
    ("/select", select),
    ("/select_jinja", select_jinja),
]

# 與路由相對應的函數,能夠自定義渲染引擎,也可使用第三方工具
def index():
    return bytes('index', encoding='utf-8')

def login():
    return bytes('login', encoding='utf-8')

# 自定義規則
def select():
    import pymysql
    conn = pymysql.connect(
        host='127.0.0.1',
        user='root',
        password='123',
        database='mydb'
    )
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    sql = "select * from users"
    cursor.execute(sql)
    
    users = cursor.fetchall()
    print(users)  # 是一個裝着字典的列表
    
    # 咱們須要在html中用@@content@@來充當佔位符,以便用數據庫中的數據來替換它,將數據渲染到網頁上
    '''
    @@content@@ 
    替換成:
    <tr>
        <td>id</td>
        <td>name</td>
        <td>age</td>
    </tr>
    '''
    
    res_list = []
    for info in users:
        res = "<tr><td>%s</td><td>%S</td><td>%s</td></tr>" %(info['id'], info['name'], info['age'])
        res_list.append(res)
    # 將列表經過join組合成字符串
    res_str = "".join(res_list)
    
    # 讀取HTML文件中的數據
    fr = open("users.html", "r", encoding="utf-8")
    data = fr.read()
    fr.close()
    
    # 將頁面中@@content@@換成數據庫中的內容
    data = data.replace("@@content@@", res_str)
    # 返回響應體結果
    return bytes(data, encoding='utf-8')
    
# 第三方工具jinja2
def select_jinja():
    import pymysql
    conn = pymysql.connect(
        host='127.0.0.1',
        user='root',
        password='123',
        database='mydb',
    )
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    sql = "select * from users"
    cursor.execute(sql)
    users = cursor.fetchall()
    
    fr = open("users_jinja.html", "r", encoding="utf-8")
    data = fr.read()
    fr.close()
    
    # 經過jinja2這個工具來實現將數據庫中的內容放到頁面中
    from jinja2 import Template
    template = Template(data)
    
    data = template.render(users=users)  # users參數是HTML文件中咱們須要替換的內容,咱們把users這個值傳過去,就能夠將頁面內容更改
    return bytes(data, encoding='utf-8')

3.自寫web框架總結

A.先寫socket服務端

B.路由系統:url ——> 函數

C.模板引擎渲染:1)本身定義的規則;2)使用第三方的工具(jinja2)

4.web框架的分類

第一種維度分類:1)A,B,C--->tornado;2)A(引入第三方),B,C --->django(wsgiref/uwsgi);3)A(引入第三方),B,C(引入第三方)--->flask

2.第二種維度分類:1)django (-orm 、-session、-form表單驗證......);2)其餘

3、django

1.django的安裝和啓動

django的安裝:
    a. pip3 install django==1.11.22 -i https://pypi.tuna.tsinghua.edu.cn/simple
    b. pycharm安裝
            
django的建立:
    a. django-admin startproject xxx
    b. pycharm建立 (*************)
                
django目錄結構:
    根目錄:
        次目錄文件夾(和根目錄同名):
            settings.py: 配置文件
            urls.py: 路由映射關係
            wsgi.py : socket服務端文件
        templates: 模板文件夾
        manage.py: 管理文件
        
啓動django服務:
    pycharm啓動

2.django的路由介紹

# urls.py中

# 添加路由和函數的對應關係:
urlpatterns = [
    # url(r'^admin/', admin.site.urls),
    url(r'^index/', index),
]
        
def index(request):
    return HttpResponse('index')

3.django的模板介紹

# urls.py中

# 模板渲染函數,自定義規則:

from django.shortcuts import HttpResponse, render

def index(request):  # django中映射函數須要request參數

    return HttpResponse('index')

def f1(request):
    ### 變量的渲染
    name = 'zekai'

    ### 列表
    li = ['zekai', 'lxxx', 'leijun']

    ### 字典
    dict = {"name":'zekai', 'age':18, 'hobby':'bj'}

    ### 列表中套字典
    myli = [
        {'id': 1, 'name': 'zekai', 'age': 12},
        {'id': 2, 'name': 'yuechun', 'age': 32},
        {'id': 3, 'name': 'lifu', 'age': 23}
    ]


    return render(request, 'f1.html', {"xxx":name, "li":li, 'dict':dict, 'myli':myli})  # render是關鍵,第三個參數是一個字典,裏面是要放入頁面中的數據庫的數據

def f2(request):
    pass

# 路由系統
urlpatterns = [
    # url(r'^admin/', admin.site.urls),
    url(r'^index/', index),
    url(r'^f1/', f1),  
]

4.操做django時的預處理

# 之後再去建立django項目的時候, 須要作的幾個操做:

# 1.到settings.py中, 配置:
    STATIC_URL = '/static/'
    STATICFILES_DIRS = (
        os.path.join(BASE_DIR, 'static'),
    )  # 逗號不能少
# 2.static目錄須要建立,將非模板文件放在靜態目錄中,好比js、css、img等靜態文件
                    
                
# 3.settings.py文件中:
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        
        'django.contrib.sessions.middleware.SessionMiddleware',
        
        'django.middleware.common.CommonMiddleware',
        
        #'django.middleware.csrf.CsrfViewMiddleware',

        'django.contrib.auth.middleware.AuthenticationMiddleware',

        'django.contrib.messages.middleware.MessageMiddleware',

        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]

# 4.
'DIRS': [os.path.join(BASE_DIR, 'templates')]

5.django的鏈接數據庫操做

1.pymysql鏈接

2.django的orm鏈接

相關文章
相關標籤/搜索