web&http協議&django初識

一、什麼是web應用

​ Web應用程序是一種能夠經過Web訪問的應用程序,程序的最大好處是用戶很容易訪問應用程序,用戶只須要有瀏覽器便可,不須要再安裝其餘軟件。css

​ 應用程序有兩種模式C/S、B/S。C/S是客戶端/服務器端程序,也就是說這類程序通常獨立運行。而B/S就是瀏覽器端/服務器端應用程序,這類應用程序通常藉助IE等瀏覽器來運行。html

​ WEB應用程序通常是B/S模式。Web應用程序首先是「應用程序」,和用標準的程序語言,如C、C++等編寫出來的程序沒有什麼本質上的不一樣。然而Web應用程序又有本身獨特的地方,就是它是基於Web的,而不是採用傳統方法運行的。換句話說,它是典型的瀏覽器/服務器架構的產物。前端

1.一、Web應用程序的優勢

  • 網絡應用程序不須要任何複雜的「展開」過程,你所須要的只是一個適用的瀏覽器;
  • 網絡應用程序一般耗費不多的用戶硬盤空間,或者一點都不耗費;
  • 它們不須要更新,由於全部新的特性都在服務器上執行,從而自動傳達到用戶端;
  • 網絡應用程序和服務器端的網絡產品都很容易結合,如email功能和搜索功能;
  • 由於它們在網絡瀏覽器窗口中運行,因此大多數狀況下它們是經過跨平臺使用的 (例如Windows,Mac,Linux等等)

1.二、Web應用程序的缺點

  • 網絡應用程序強調瀏覽器的適用性。若是瀏覽器方沒有提供特定的功能,或者棄用特定的平臺或操做系統版本(致使不適用),就會影響大量用戶;
  • 網絡應用依靠互聯網遠程服務器端的應用文件。所以,當鏈接出問題時,應用將不能正常使用。
  • 許多網絡應用程序不是開源的,只能依賴第三方提供的服務,所以不能針對用戶定製化、個性化,並且大多數狀況下用戶不能離線使用,於是損失了不少靈活性;
  • 它們徹底依賴應用服務商的可及性。若是公司倒閉,服務器中止使用,用戶也沒法追索之前的資料。對比而看,即便軟件製造商倒閉了,傳統的安裝軟件也能夠繼續運行,儘管不能再更新或有其餘用戶服務;
  • 類似地,提供方公司對軟件和其功能有了更大的控制權。只要他們願意就能爲軟件添加新特性,即便用戶想等bugs先被解決再更新。跳過較差的軟件版本也不可能了。公司能夠強加不受歡迎的特性給用戶,也能夠隨意減小帶寬來削減開支。
  • 公司理論上能夠檢索任何的用戶行爲。這有可能引發隱私安全問題。

1.三、B/S架構優勢

​ 瀏覽器/服務器架構(Browser/Server,簡稱B/S)可以很好地應用在廣域網上,成爲愈來愈多的企業的選擇。瀏覽器/服務器架構相對於其餘幾種應用程序體系結構,有以下3方面的優勢:python

  • 這種架構採用Internet上標準的通訊協議(一般是TCP/IP協議)做爲客戶機同服務器通訊的協議。這樣可使位於Internet任意位置的人都可以正常訪問服務器。對於服務器來講,經過相應的Web服務和數據庫服務能夠對數據進行處理。對外採用標準的通訊協議,以便共享數據。mysql

  • 在服務器上對數據進行處理,就處理的結果生成網頁,以方便客戶端直接下載。jquery

  • 在客戶機上對數據的處理被進一步簡化,將瀏覽器做爲客戶端的應用程序,以實現對數據的顯示。再也不須要爲客戶端單獨編寫和安裝其餘類型的應用程序。這樣,在客戶端只須要安裝一套內置瀏覽器的操做系統,直接安裝一套瀏覽器,就能夠實現服務器上數據的訪問。而瀏覽器是計算機的標準設備。web

    總結一下,本質上:瀏覽器是一個socket客戶端,服務器是一個socket服務端面試

二、HTTP協議

​ 超文本傳輸協議:規定了客戶端與服務端消息傳輸的格式sql

四大特性:

​ 1.基於TCP/IP協議做用於應用層的協議
​ 2.基於請求響應
​ 3.無狀態
​ 4.無鏈接
數據庫

數據格式之請求:

​ 請求首行
​ 請求頭(一堆k,v鍵值對)

​ 請求體(post請求攜帶的數據)

數據格式之響應:

​ 響應首行
​ 響應頭(一堆k,v鍵值對)

​ 響應體(post請求攜帶的數據)

響應狀態碼

​ 1XX 服務器已經成功接受到你的數據正在處理,你能夠繼續提交其餘數據
​ 2XX 請求成功 服務器已經將你請求的數據發送給你了
​ 3XX 重定向
​ 4XX 請求資源不存在
​ 5XX 服務器錯誤

三、動靜態網頁

​ 靜態網頁:
​ 頁面上的數據都是寫死的,萬年不變。
​ 動態網頁:
​ 頁面上的數據是從後端動態獲取的。
​ 好比後端獲取當前時間。
​ 後端獲取數據庫數據而後傳遞給前端頁面。

四、模板渲染

後端生成的數據直接傳遞給前端頁面使用(而且前端頁面能夠靈活的操做改數據) >>> 模板語法

模板渲染 模板語法須要依賴於第三方模塊
pip install jinja2

模板語法  jinja2支持前端直接使用相似於python的語法操做數據
<p>{{ user_dic }}</p>
<p>{{ user_dic.name }}</p>
<p>{{ user_dic['password'] }}</p>
<p>{{ user_dic.get('name') }}</p>
    
{% for user in user_dict %}  <!--[{},{},{},{}]-->
    <tr>
        <td>{{ user.id }}</td>
        <td>{{ user.name }}</td>
        <td>{{ user.password }}</td>
    </tr>
{% endfor %}

五、手擼web框架

import socket

server = socket.socket()  #不傳參數默認就是TCP協議
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)
    """
    請求首行
    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數據獲取用戶訪問的路徑
    current_path = data.decode('utf-8').split('\r\n')[0].split(' ')[1]
    if current_path == '/index':
        # 路由匹配上以後返回index
        # conn.send(b'<h1>index</h1>')
        with open('index.html','rb') as f:
            conn.send(f.read())
    else:
        conn.send(b'404')
    conn.close()
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>
<h1>index</h1>
</body>
</html>

六、編碼解碼小技巧

data = b'hello'

data = str(data,encoding='utf-8')
data = bytes(data,encoding='utf-8')

七、基於wsgiref擼框架

#  基於wsgiref的框架.py

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

def run(env,response):
    """
    :param env:請求相關的信息
    :param response:響應相關的信息
    :return:
    """
    print(env)  # 是一個大字典 裏面裝了一堆處理好了的鍵值對數據 {...,'PATH_INFO':'/get_db',...}
    response('200 OK',[('username','jason'),('password','123')])  # 固定寫法
    # 獲取用戶訪問的路徑
    current_path = env.get('PATH_INFO')   # '/get_db'
    
    # if current_path == '/index':
    #       return [b'index']
    # elif current_path == '/login':
    #       return [b'login']
    # else:
    #       return [b'404']
    
    # 定義一個存儲函數名的變量名
    func = None
    # 循環比對路由與視圖函數的映射關係
    for url_map in urls:  # url_map = ('/get_db',get_db)
        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
from jinja2 import Template
import pymysql

# 靜態頁面
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(r'templates/get_time.html','r',encoding='utf-8') as f:
        data = f.read()
    # 由於是以r模式打開的文件,因此獲取到的內容就是一堆字符串
    res = data.replace('@@time@@',current_time)  # 字符串的替換
    return res

# 經過jinja2渲染直接在html文件裏相似於python語法同樣操做字典等數據
def get_user(env):
    with open(r'templates/get_user.html','r',encoding='utf-8') as f:
        data = f.read()
    tmp = Template(data)
    # 將字典傳遞給前端頁面 前端經過變量名user_dic就能夠獲取到該字典
    return tmp.render(user_dic={'name':'jason','password':'123'})

# 實現操做數據庫把數據返回給客戶端頁面
def get_db(env):
    # 鏈接數據庫 獲取數據 渲染到前端頁面
    conn = pymysql.connect(
        host = '127.0.0.1',
        port = 3306,
        user = 'root',
        password = '123456',
        database = 'day54',
        charset = 'utf8',
        autocommit = True
    )
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    cursor.execute('select * from userinfo')
    user_dict = cursor.fetchall()  # [{},{},{}]
    with open(r'templates/get_db.html','r',encoding='utf-8') as f:
        data = f.read()
    tmp = Template(data)
    return tmp.render(user_dict=user_dict) 
    
# 返回輸入信息不存在的錯誤信息
def error(env):
    return '404 error'
<!--  /templates (文件夾:專門用來存放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>
</head>
<body>
@@time@@
</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>
</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_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>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <table class="table table-hover table-striped table-bordered">
                <thead>
                    <tr>
                        <th>id</th>
                        <th>name</th>
                        <th>password</th>
                    </tr>
                </thead>
                <tbody>
                    {% for user in user_dict %}
                        <tr>
                            <td>{{ user.id }}</td>
                            <td>{{ user.name }}</td>
                            <td>{{ user.password }}</td>
                        </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
</div>
{{ user_dict }}   <!-- [{}},{}},{}}] -->
</body>
</html>
//  數據庫設計
id   name    password
1    jason   123
2    owen    123
3    egon    123
4    tank    123

八、什麼是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都是本身寫的

九、使用Djangon前的3個注意事項

​ 一、計算機的名稱不能有中文

​ 二、一個pycharm窗口就是一個項目,不要多個項目放在同一個窗口裏

​ 三、項目名不能起中文

十、Django簡介

10.一、版本問題

django下載

​ 推薦下載1.11.11版本
​ 命令行直接下載
​ pip3 install django==1.11.11
​ pycharm下載

​ ps:出去面試的時候,說本身一開始是用的1.8版本,而後向1.11版本轉

驗證是否下載成功

​ django-admin

10.二、建立django項目的方式

方式1(命令行建立)

​ 建立django項目

​ django-admin startproject 項目名

​ 建立app應用

​ python3 manage.py startapp app01

bug:pyhton3.7版本建立app應用時會報錯,解決方法是點擊最後一行報錯信息,去掉('%s=%s' % (k, v) for k, v in params.items(),)後面的逗號便可。

​ 啓動django項目

​ python3 manage.py runserver

​ ps:用命令行建立django默認不會自動建立templates文件夾
​ 須要你手動本身建立(注意該文件夾路徑是否被添加配置文件中)

方式2 (pycharm建立)

​ FILE >>> new project 選擇第二個django 須要注意名字不能有中文,選擇本地的解釋器,勾選後臺管理
​ 建立app
​ pycharm命令行建立
​ python3 manage.py startapp app01
​ Tools下面run manage task功能欄
​ 啓動點小綠色箭頭

強調:

​ 1.用django必定要保證只有一個在運行狀態 切記切記!!!!!!!
​ 2.必定記得清瀏覽器的緩存

10.三、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'                  # 也能夠簡寫
]

10.四、django各個文件的做用

應用名
migrations 數據庫遷移記錄相關數據
admin.py django後臺管理相關
models.py 模型表相關
views.py 視圖函數相關
項目名
settings.py 配置文件
urls.py 路由與視圖函數的映射關係
templates
項目用到的全部的html文件
manage.py
django入口文件

10.五、django小白必會三板斧

from django.shortcuts import render,HttpResponse,redirect

HttpResponse  返回字符串
        def index(request):
            return 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())  # locals會將全部的變量名都傳給html頁面
            
redirect      重定向(跳轉到其餘界面)
        def login(request):
            return redirect('https://www.baidu.com')

注意:django識別到你的代碼變化以後會自動,可是有時候反應速度比較慢 ​ 你能夠手動重啓,你也能夠多刷新幾回瀏覽器

相關文章
相關標籤/搜索