Django 初識

咱們能夠這樣理解:全部的Web應用本質上就是一個socket服務端,而用戶的瀏覽器就是一個socket客戶端。 這樣咱們就能夠本身實現Web框架了。html

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

import socket
import time

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


# 將返回不一樣的內容部分封裝成函數
def index(url):
    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(url):
    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

服務器程序和應用程序

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

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

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

 

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

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

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

經常使用的WSGI服務器有uwsgi、Gunicorn。而Python標準庫提供的獨立WSGI服務器叫wsgiref,Django開發環境用的就是這個模塊來作服務器。服務器

 

從這繼續...session

wsgiref

咱們利用wsgiref模塊來替換咱們本身寫的web框架的socket server部分:

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

import time
from wsgiref.simple_server import make_server


# 將返回不一樣的內容部分封裝成函數
def index(url):
    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(url):
    with open("home.html", "r", encoding="utf8") as f:
        s = f.read()
    return bytes(s, encoding="utf8")


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


def run_server(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ])  # 設置HTTP響應的狀態碼和頭信息
    url = environ['PATH_INFO']  # 取到用戶輸入的url
    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!"
    return [response, ]


if __name__ == '__main__':
    httpd = make_server('127.0.0.1', 8090, run_server)
    print("我在8090等你哦...")
    httpd.serve_forever()
複製代碼

jinja2

上面的代碼實現了一個簡單的動態,我徹底能夠從數據庫中查詢數據,而後去替換我html中的對應內容,而後再發送給瀏覽器完成渲染。 這個過程就至關於HTML模板渲染數據。 本質上就是HTML內容中利用一些特殊的符號來替換要展現的數據。 我這裏用的特殊符號是我定義的,其實模板渲染有個現成的工具: jinja2

下載jinja2:

pip install jinja2
  index2.html文件

使用jinja2渲染index2.html文件:

複製代碼
from wsgiref.simple_server import make_server
from jinja2 import Template


def index():
    with open("index2.html", "r") as f:
        data = f.read()
    template = Template(data)  # 生成模板文件
    ret = template.render({"name": "Alex", "hobby_list": ["燙頭", "泡吧"]})  # 把數據填充到模板裏面
    return [bytes(ret, encoding="utf8"), ]


def home():
    with open("home.html", "rb") as f:
        data = f.read()
    return [data, ]


# 定義一個url和函數的對應關係
URL_LIST = [
    ("/index/", index),
    ("/home/", home),
]


def run_server(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ])  # 設置HTTP響應的狀態碼和頭信息
    url = environ['PATH_INFO']  # 取到用戶輸入的url
    func = None  # 將要執行的函數
    for i in URL_LIST:
        if i[0] == url:
            func = i[1]  # 去以前定義好的url列表裏找url應該執行的函數
            break
    if func:  # 若是能找到要執行的函數
        return func()  # 返回函數的執行結果
    else:
        return [bytes("404沒有該頁面", encoding="utf8"), ]


if __name__ == '__main__':
    httpd = make_server('', 8000, run_server)
    print("Serving HTTP on port 8000...")
    httpd.serve_forever()
複製代碼

如今的數據是咱們本身手寫的,那可不能夠從數據庫中查詢數據,來填充頁面呢?

使用pymysql鏈接數據庫:

複製代碼
conn = pymysql.connect(host="127.0.0.1", port=3306, user="root", passwd="xxx", db="xxx", charset="utf8")
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute("select name, age, department_id from userinfo")
user_list = cursor.fetchall()
cursor.close()
conn.close()
複製代碼

建立一個測試的user表:

CREATE TABLE user(
  id int auto_increment PRIMARY KEY,
  name CHAR(10) NOT NULL,
  hobby CHAR(20) NOT NULL
)engine=innodb DEFAULT charset=UTF8;

模板的原理就是字符串替換,咱們只要在HTML頁面中遵循jinja2的語法規則寫上,其內部就會按照指定的語法進行相應的替換,從而達到動態的返回內容。

Django

Django官網下載頁面

安裝(安裝最新LTS版):

pip3 install django==1.11.9

建立一個django項目:

下面的命令建立了一個名爲"mysite"的Django 項目:

django-admin startproject mysite

目錄介紹:

複製代碼
mysite/
├── manage.py  # 管理文件
└── mysite  # 項目目錄
    ├── __init__.py
    ├── settings.py  # 配置
    ├── urls.py  # 路由 --> URL和函數的對應關係
    └── wsgi.py  # runserver命令就使用wsgiref模塊作簡單的web server
複製代碼

運行Django項目:

python manage.py runserver 127.0.0.1:8000

模板文件配置:

複製代碼
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "template")],  # template文件夾位置
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
複製代碼

靜態文件配置:

STATIC_URL = '/static/'  # HTML中使用的靜態文件夾前綴
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),  # 靜態文件存放位置
]

看不明白?有圖有真相:

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

複製代碼
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',
]
複製代碼
相關文章
相關標籤/搜索