Django學習筆記1

Web框架本質

全部的Web應用本質上就是一個socket服務端,而用戶的瀏覽器就是一個socket客戶端。 這樣咱們就能夠本身實現Web框架了。咱們定義一個socket server端程序,與瀏覽器(client端)進行互交試試css

import socket

sk = socket.socket()
sk.bind(("127.0.0.1", 8001))
sk.listen()


while True:
    conn, addr = sk.accept()
    data = conn.recv(8096)
    print(data)  # 將瀏覽器發來的消息打印出來
    conn.send(b"OK")
    conn.close()

b'GET / HTTP/1.1\r\nHost: 127.0.0.1:8001\r\nConnection: keep-alive\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nDNT: 1\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\nCookie: csrftoken=RKBXh1d3M97iz03Rpbojx1bR6mhHudhyX5PszUxxG3bOEwh1lxFpGOgWN93ZH3zv\r\n\r\n'

服務端收到了http的請求頭,如此就能夠和客戶端進行互交了。因此能夠說Web服務本質上都是在這十幾行代碼基礎上擴展出來的,只要請求和響應知足必定的規範(http協議),就能夠實現咱們寫的server端和client端進行互交了。html

HTTP協議詳解:http://www.javashuo.com/article/p-ojnddlxm-o.htmlpython

HTTP GET請求的格式:

HTTP響應的格式:

定義本身的簡易web框架

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('127.0.0.1', 8000))
sock.listen()

while True:
    conn, addr = sock.accept()
    data = conn.recv(8096)
    # 給回覆的消息加上響應狀態行
    conn.send(b"HTTP/1.1 200 OK\r\n\r\n")  # 包括響應行和響應頭和換行
    conn.send(b"OK")  # 回覆響應正文
    conn.close()

此時在訪問127.0.0.1:8000便可獲得OK界面web

根據不一樣的路徑返回不一樣的內容

如何讓咱們的Web服務根據用戶請求的URL不一樣而返回不一樣的內容呢?數據庫

"""
根據URL中不一樣的路徑返回不一樣的內容,返回獨立的HTML頁面
"""

import socket
sk = socket.socket()
sk.bind(("127.0.0.1", 8080))  # 綁定IP和端口
sk.listen()  # 監聽


# 將返回不一樣的內容部分封裝成函數
def index(request):
    # 讀取index.html頁面的內容
    with open("index.html", "r", encoding="utf8") as f:
        s = f.read()
    # 返回字節數據
    return bytes(s, encoding="utf8")


def home(request):
    with open("home.html", "r", encoding="utf8") as f:
        s = f.read()
    return bytes(s, encoding="utf8")


# 定義一個url和實際要執行的函數的對應關係
list1 = [
    ("/index/", index),
    ("/home/", home),
]

while 1:
    # 等待鏈接
    conn, add = sk.accept()
    data = conn.recv(8096)  # 接收客戶端發來的消息
    # 從data中取到路徑
    data = str(data, encoding="utf8")  # 把收到的字節類型的數據轉換成字符串
    # 按\r\n分割
    data1 = data.split("\r\n")[0]
    url = data1.split()[1]  # url是咱們從瀏覽器發過來的消息中分離出的訪問路徑
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')  # 由於要遵循HTTP協議,因此回覆的消息也要加狀態行
    # 根據不一樣的路徑返回不一樣內容
    func = None  # 定義一個保存將要執行的函數名的變量
    for i in list1:
        if i[0] == url:
            func = i[1]
            break
    if func:
        response = func(url)
    else:
        response = b"404 not found!"

    # 返回具體的響應消息
    conn.send(response)
    conn.close()

這樣便可實現根據不一樣的url返回不一樣的界面express

讓網頁動態起來

這網頁可以顯示出來了,可是都是靜態的啊。頁面的內容都不會變化的,我想要的是動態網站。django

沒問題,我也有辦法解決。我選擇使用字符串替換來實現這個需求。(這裏使用時間戳來模擬動態的數據)flask

"""
根據URL中不一樣的路徑返回不一樣的內容--函數進階版
返回HTML頁面
讓網頁動態起來
"""

import socket
import time

sk = socket.socket()
sk.bind(("127.0.0.1", 8080))  # 綁定IP和端口
sk.listen()  # 監聽


# 將返回不一樣的內容部分封裝成函數
def index(request):
    with open("index.html", "r", encoding="utf8") as f:
        s = f.read()
        now = str(time.time())
        s = s.replace("@@oo@@", now)  # 在網頁中定義好特殊符號,用動態的數據去替換提早定義好的特殊符號
    return bytes(s, encoding="utf8")


def home(request):
    with open("home.html", "r", encoding="utf8") as f:
        s = f.read()
    return bytes(s, encoding="utf8")


# 定義一個url和實際要執行的函數的對應關係
list1 = [
    ("/index/", index),
    ("/home/", home),
]

while 1:
    # 等待鏈接
    conn, add = sk.accept()
    data = conn.recv(8096)  # 接收客戶端發來的消息
    # 從data中取到路徑
    data = str(data, encoding="utf8")  # 把收到的字節類型的數據轉換成字符串
    # 按\r\n分割
    data1 = data.split("\r\n")[0]
    url = data1.split()[1]  # url是咱們從瀏覽器發過來的消息中分離出的訪問路徑
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')  # 由於要遵循HTTP協議,因此回覆的消息也要加狀態行
    # 根據不一樣的路徑返回不一樣內容
    func = None  # 定義一個保存將要執行的函數名的變量
    for i in list1:
        if i[0] == url:
            func = i[1]
            break
    if func:
        response = func(url)
    else:
        response = b"404 not found!"

    # 返回具體的響應消息
    conn.send(response)
    conn.close()

本質到這已經講完了,下面講框架的基礎設計模式

服務器程序和應用程序

對於真實開發中的python web程序來講,通常會分爲兩部分:服務器程序和應用程序。瀏覽器

服務器程序負責對socket服務器進行封裝,並在請求到來時,對請求的各類數據進行整理。

應用程序則負責具體的邏輯處理。爲了方便應用程序的開發,就出現了衆多的Web框架,例如:Django、Flask、web.py 等。不一樣的框架有不一樣的開發方式,可是不管如何,開發出的應用程序都要和服務器程序配合,才能爲用戶提供服務。

 

這樣,服務器程序就須要爲不一樣的框架提供不一樣的支持。這樣混亂的局面不管對於服務器仍是框架,都是很差的。對服務器來講,須要支持各類不一樣框架,對框架來講,只有支持它的服務器才能被開發出的應用使用。

這時候,標準化就變得尤其重要。咱們能夠設立一個標準,只要服務器程序支持這個標準,框架也支持這個標準,那麼他們就能夠配合使用。一旦標準肯定,雙方各自實現。這樣,服務器能夠支持更多支持標準的框架,框架也可使用更多支持標準的服務器。

WSGI(Web Server Gateway Interface)就是一種規範,它定義了使用Python編寫的web應用程序或框架與web服務器程序之間的接口格式,實現web應用程序與web服務器程序間的解耦。

經常使用的WSGI服務器有uwsgi(性能比wsgiref好)、Gunicorn。而Python標準庫提供的獨立WSGI服務器叫wsgiref(本質是socket服務器),Django開發環境用的就是這個模塊來作服務器,Werkuzeug也是實現了wsgi的模塊(flask使用),下面wsgi左右的都是服務器,不過各自的功能不一樣,具體功能看下面的abc

 

 

web框架本質和Python中 Web框架的分類

web框架的本質:
socket服務端 與 瀏覽器的通訊

socket服務端功能劃分:
a. 負責與瀏覽器收發消息(socket通訊) --> wsgiref/uWsgi/gunicorn...
b. 根據用戶訪問不一樣的路徑執行不一樣的函數
c. 從HTML讀取出內容,而且完成字符串的替換 --> jinja2(模板語言)

Python中 Web框架的分類:

按上面三個功能劃分:

1. 框架自帶a,b,c --> Tornado
2. 框架自帶b和c,使用第三方的a --> Django  第三方的a是wsgiref
3. 框架自帶b,使用第三方的a和c --> Flask  第三方的a是Werkzeug,c是jinja2

按另外一個維度來劃分:

1. Django --> 大而全(你作一個網站能用到的它都有)
2. 其餘 --> Flask 輕量級

Django框架簡介

MVC框架和MTV框架

MVC,全名是Model View Controller,是軟件工程中的一種軟件架構模式,把軟件系統分爲三個基本部分:模型(Model)、視圖(View)和控制器(Controller),具備耦合性低、重用性高、生命週期成本低等優勢。

Django框架的設計模式借鑑了MVC框架的思想,也是分紅三部分,來下降各個部分之間的耦合性。

Django框架的不一樣之處在於它拆分的三部分爲:Model(模型)、Template(模板)和View(視圖),也就是MTV框架。

Django的MTV模式

       Model(模型):負責業務對象與數據庫的對象(ORM)

       Template(模版):負責如何把頁面展現給用戶

       View(視圖):負責業務邏輯,並在適當的時候調用Model和Template

此外,Django還有一個urls分發器,它的做用是將一個個URL的頁面請求分發給不一樣的view處理,view再調用相應的Model和Template

Django框架圖示

完整的簡易請求流程

0. 啓動服務端,等待客戶端(用戶的瀏覽器)來鏈接
1. 在瀏覽器地址欄輸入URL,與服務端創建鏈接,瀏覽器發送請求
2. 服務端收到請求消息,解析請求消息,根據路徑和函數的對應關係,找到將要執行的函數
3. 執行函數,打開HTML文件,進行字符串替換,獲得一個最終要返回的HTML內容
4. 按照HTTP協議的消息格式要求,把HTML內容回覆給用戶瀏覽器(發送響應)
5. 瀏覽器收到響應的消息以後,按照HTML的規則渲染頁面.
6. 關閉鏈接

Django的安裝和啓動

安裝(安裝最新LTS版)

LTS爲官方長期維護的版本:

 

這裏有1.11版本的官方翻譯文檔,我看的時候官方翻譯的文檔沒有1.11版本的,只有2.0及之後的,若看2.0之後,直接去官方看便可

1.11的中文文檔  還有 2.0的官方文檔

運行下面指令安裝完成便可使用django-admin命令查看

pip3 install django==1.11.11

執行完成會在當前目錄下安裝django

建立一個django項目

(一)命令行建立方式(不推薦使用)

     1. cd到你要保存Django項目的目錄
     2. Django-admin startproject 項目名   --> 會在當前目錄建立Django項目

django-admin startproject mysite
# 若Django未加入到環境變量,能夠到目錄下找django文件 H:\python\venvs\Mydjango\Scripts\django-admin startproject newdjango

(二)pycharm中建立django項目

  1.首先你要有一個安裝了django的python解釋器(沒有的話pycharm通常也會幫忙建立,自動調用pip命令安裝django,個別版本會有問題)

    1.若是是安裝的純淨的解釋器(官網直接下的):cd到解釋器安裝目錄下Script目錄的位置(裏面有pip.exe的那個),而後執行pip3 install django==1.11.11,這時你就有一個安裝了django的python解釋器

    2.若是是pycharm中建立的虛擬環境,直接在虛擬環境的帶有python.exe的同級目錄下執行pip3 install django==1.11.11

    3.若是是別的虛擬環境。。。。。我也不會

  2.而後點擊新建項目(選擇安裝了django的python解釋器

而後就能夠了,測試是否建立成功就在項目裏執行一下,而後點擊控制檯的連接,而後就能夠看到祝賀界面

也能夠在命令行界面啓動,保證本身保持和manage.py在同一目錄下,而後執行 

python manage.py runserver

你應該會看到以下輸出:

Performing system checks...

System check identified no issues (0 silenced).

You have unapplied migrations; your app may not work properly until they are applied.
Run 'python manage.py migrate' to apply them.

十月 23, 2018 - 15:50:53
Django version 2.1, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

而後點擊控制檯的連接,而後就能夠看到祝賀界面

啓動Django報錯:

Django啓動:

Django項目在pycharm中啓動時,不要運行單個文件,要點擊綠色三角運行

命令行啓動

在項目的根目錄下(也就是有manage.py的那個目錄),運行:

python3 manage.py runserver IP:端口--> 在指定的IP和端口啓動
python3 manage.py runserver 端口 --> 在指定的端口啓動
python3 manage.py runserver --> 默認在本機的8000端口啓動

Django 啓動時報錯 「UnicodeEncodeError ...」

報這個錯誤一般是由於計算機名爲中文,改爲英文的計算機名重啓下電腦就能夠了。

Django 啓動報錯「SyntaxError: Generator expression must be parenthesized」

報這個錯很大多是由於使用了Python3.7.0,而目前(2018-06-12)Python3.7.0和Django還有點兼容性問題,換回Python3.6的環境便可。

剛開始學習時可在配置文件中暫時禁用csrf中間件,方便表單提交測試。

目錄簡單介紹

一、外層總目錄介紹

在執行完    django-admin startproject mysite   的建立

mysite/  # 項目根目錄
├── manage.py  # 管理文件,互交命令行工具
└── mysite  # 項目目錄(純Python包)
    ├── __init__.py  # Python包必帶
    ├── settings.py  # 配置
    ├── urls.py  # 路由 --> URL和函數(類)的對應關係
    └── wsgi.py  # runserver命令就使用wsgiref模塊作簡單的web server

這些文件是:

  • 外層的mysite/根目錄僅僅是項目的一個容器。 它的名字與Django無關;能夠將其重命名爲你喜歡的任何內容。
  • manage.py:一個命令行工具,可使你用多種方式對Django項目進行交互。 你能夠在django-admin和manage.py中讀到關於manage.py的全部細節。
  • 內層的mysite/目錄是你的項目的真正的Python包。 它是你導入任何東西時將須要使用的Python包的名字(例如 mysite.urls)。
  • mysite/__init__.py:一個空文件,它告訴Python這個目錄應該被看作一個Python包。 若是你是Python初學者,請在官方Python文檔中閱讀關於python包的更多內容
  • mysite/settings.py:該Django 項目的設置/配置。 Django settings 將告訴你這些設置如何工做。
  • mysite/urls.py:此Django項目的URL聲明;Django驅動的網站的「目錄」。 你能夠在URL dispatcher 中閱讀到更多關於URL的內容。
  • mysite/wsgi.py:用於你的項目的與WSGI兼容的Web服務器入口。 更多細節請參見如何使用WSGI部署

 二、APP層目錄介紹

應用和項目的區別:

項目和應用之間有什麼不一樣? 應用是一個Web應用程序,它完成具體的事項 —— 好比一個博客系統、一個存儲公共檔案的數據庫或者一個簡單的投票應用。 一個項目是特定網站的配置和應用程序的集合。 一個項目能夠包含多個應用。 一個應用能夠運用到多個項目中去。

要建立你的應用,請確保與manage.py在同一目錄中,並鍵入如下命令:

python manage.py startapp polls

  這將建立一個目錄polls,它的結構以下:

polls/
    __init__.py
    admin.py
    apps.py
    migrations/
        __init__.py
    models.py
    tests.py
    views.py

       一、migrations目錄:此目錄記錄了數據庫變化狀況

       二、admin.py文件: Django 爲咱們提供的後臺管理

       三、apps.py文件:配置當前app

       四、models.py文件:此文件用來定義數據庫表,ORM,寫指定的類,經過命令能夠建立數據庫結構

       五、tests.py文件:此文件用於單元測試

       六、urls.py文件:此文件是APP本身的路由規則所在的文件(上面目錄沒有,是二級路由時用,可手動建立)

       七、views.py文件:此文件是視圖函數的代碼所在文件,關於視圖函數會在後面的博客中詳細介紹

 三、靜態文件目錄

建立工程完成後,咱們須要在工程根目錄下建立一個「static」目錄用戶保存靜態文件。

關於靜態文件,在網站中,那些圖片、css、js等通常狀況下內容不會變化的文件都是靜態文件,咱們能夠把這些文件都放這個靜態文件目錄中。

靜態目錄建立完成後須要在settings.py文件中添加以下的配置:

STATIC_URL = '/static/'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR,'static'),
)

四、模板文件目錄

  模板文件就是指那些html文件,在用戶訪問的過程當中,Django會將頁面上的數據套用到模板文件,渲染成一個完整的字符串而後返回給客戶端,這些模板文件存放在templates目錄中,關於模板文件以及模板語言的語法將會在後續的博客中詳細介紹。

 

總目錄http://www.javashuo.com/article/p-bjvpxucg-r.html

相關文章
相關標籤/搜索