第十二章 Django框架 12.1 伺服器程式和應用程式 伺服器程式負責對socket伺服器進行封裝,併在請求到來時,對請求的各種數據進行整理。應用程式則負責具體的邏輯處理。為了方便應用程式的開發,就出現了眾多的Web框架,例如:Django、Flask、web.py 等。不同的框架有不同的開發方 ...
第十二章 Django框架
12.1 伺服器程式和應用程式
伺服器程式負責對socket伺服器進行封裝,併在請求到來時,對請求的各種數據進行整理。應用程式則負責具體的邏輯處理。為了方便應用程式的開發,就出現了眾多的Web框架,例如:Django、Flask、web.py 等。不同的框架有不同的開發方式,但是無論如何,開發出的應用程式都要和伺服器程式配合,才能為用戶提供服務。
WSGI(Web Server Gateway Interface)就是一種規範,它定義了使用Python編寫的web應用程式與web伺服器程式之間的介面格式,實現web應用程式與web伺服器程式間的解耦。
常用的WSGI伺服器有uwsgi、Gunicorn,而Python標準庫提供的獨立WSGI伺服器叫wsgiref,Django開發環境用的就是這個模塊來做伺服器。
12.11 用wsgiref代替socket server
import time from wsgiref.simple_server import make_server def home(url): # 將返回不同的內容部分封裝成函數 s = "this is {} page!".format(url) return bytes(s, encoding="utf8") def index(url): return b'<h1>index page</h1>' def user(url): # 不同的用戶得到的頁面上顯示不同的時間 c_time = str(time.time()) with open("user.html", "r") as f: data_s = f.read() data_s = data_s.replace("@@xx@@", c_time) return bytes(data_s, encoding="utf8") url2func = [ # url和實際要執行的函數的對應關係 ("/index/", index), ("/home/", home), ("/user/", user),] def run_server(environ, start_response):# 按照wsgiref的要求定義一個run_server函數 start_response('200 OK',[('Content-Type','text/html;charset=utf8'),])#設置HTTP響應的狀態碼和頭信息 url = environ['PATH_INFO'] # 取到用戶輸入的url func = None for i in url2func: if url == i[0]: func = i[1] # 拿到將要執行的函數 break if func: msg = func(url) # 執行對應的函數 else: msg = b'<h1>404</h1>' # 找不到要執行的函數就返回404 return [msg, ] # 發送消息到客戶端 if __name__ == '__main__': httpd = make_server('127.0.0.1', 8090, run_server) print("我在8090等你哦...") httpd.serve_forever()
12.12 HTML模板渲染工具jinja2
user.html:
<body> <table border="1"> <thead> <tr> <th>id</th> <th>姓名</th> <th>愛好</th> </tr> </thead> <tbody> {% for user in user_list %} <tr> <td>{{user.id}}</td> <td>{{user.name}}</td> <td>{{user.hobby}}</td> </tr> {% endfor %} </tbody> </table> </body>
使用jinjia2替換HTML中的數據:
使用pymysql模塊查詢資料庫獲取數據,使用jinjia2替換HTML中的數據
模板的原理就是字元串替換,我們只要在HTML頁面中遵循jinja2的語法規則,其內部就會按照指定的語法進行相應的替換,從而達到動態的返回內容
import time from wsgiref.simple_server import make_server from jinja2 import Template import pymysql def user(url): conn = pymysql.connect( # 從資料庫裡面去到所有的用戶信息, host='127.0.0.1', port=3306, user='root', password='123', database='db6', charset='utf8' ) cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) cursor.execute('select * from user') ret = cursor.fetchall() #print(ret) with open("user.html", "r", encoding="utf8") as f: data_s = f.read() template = Template(data_s) # 生成一個模板文件實例 msg = template.render({"user_list": ret}) # 把數據填充到模板裡面 return bytes(msg, encoding="utf8") url2func = [ # url和將要執行的函數的對應關係 ("/index/", index), ("/home/", home), ("/user/", user),] def run_server(environ, start_response): # 按照wsgiref的要求定義一個run_server函數 start_response('200 OK',[('Content-Type','text/html;charset=utf8'),])#設置HTTP響應的狀態碼和頭信息 url = environ['PATH_INFO'] # 取到用戶輸入的url func = None for i in url2func: if url == i[0]: func = i[1] # 拿到將要執行的函數 break if func: msg = func(url) # 執行對應的函數 else: msg = b'<h1>404</h1>' # 找不到要執行的函數就返回404 return [msg, ] # 發送消息到客戶端 if __name__ == '__main__': httpd = make_server('127.0.0.1', 8090, run_server) print("我在8090等你哦...") httpd.serve_forever()
12.2 Django基礎必備三件套
用命令創建了一個名為"mysite"的Django 項目
django-admin startproject mysite
Django目錄:
mysite/ ├── manage.py # 管理文件 └── mysite # 項目目錄 ├── __init__.py ├── settings.py # 配置 ├── urls.py # 路由 --> URL和函數的對應關係 └── wsgi.py # runserver命令就使用wsgiref模塊做簡單的 web server
用命令運行Django項目
python3 manage.py runserver 127.0.0.1:8000 #預設使用8000埠
模板文件配置:settings
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', ], }, }, ]
靜態文件配置:settings
STATIC_URL = '/static/' # HTML中使用的靜態文件夾首碼 STATICFILES_DIRS = [ os.path.join(BASE_DIR, "static"), # 靜態文件存放位置 ]
12.21 HttpResponse
內部傳入一個字元串參數,返回給瀏覽器
from django.conf.urls import url from django.contrib import admin from django.shortcuts import HttpResponse, render, redirect def index(request): #所有跟請求相關的數據都封裝到了request這個參數裡面 # 業務邏輯代碼 return HttpResponse("這是index頁面!")
12.22 render
除request參數外還接受一個待渲染的模板文件和一個保存具體數據的字典參數,將數據填充進模板文件,最後把結果返回給瀏覽器(類似於上面用到的jinja2)
def login(request): # 自己去找HTML文件 # with open("templates/login.html", "r", encoding="utf8") as f: # data = f.read() # return HttpResponse(data) # Django去找login.html文件,讀取出來內容,返回給瀏覽器 return render(request, "login.html", {"name": "alex", "hobby": ["燙頭", "泡吧"]})
12.23 redirect
接受一個URL參數,表示跳轉到指定的URL
def index(request): # 業務邏輯代碼 return redirect("/home/")
12.24 設置URL和函數的對應關係
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^home/', home), url(r'^index/', index), url(r'^login/', login), ]