日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Web框架本质

發(fā)布時間:2024/1/17 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Web框架本质 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Web框架本質(zhì)及第一個Django實例

Web框架本質(zhì)

我們可以這樣理解:所有的Web應(yīng)用本質(zhì)上就是一個socket服務(wù)端,而用戶的瀏覽器就是一個socket客戶端。 這樣我們就可以自己實現(xiàn)Web框架了。

半成品自定義web框架

import socketsk = socket.socket() sk.bind(("127.0.0.1", 80)) sk.listen()while True:conn, addr = sk.accept()data = conn.recv(8096)conn.send(b"OK")conn.close()

可以說Web服務(wù)本質(zhì)上都是在這十幾行代碼基礎(chǔ)上擴(kuò)展出來的。這段代碼就是它們的祖宗。

用戶的瀏覽器一輸入網(wǎng)址,會給服務(wù)端發(fā)送數(shù)據(jù),那瀏覽器會發(fā)送什么數(shù)據(jù)?怎么發(fā)?這個誰來定? 你這個網(wǎng)站是這個規(guī)定,他那個網(wǎng)站按照他那個規(guī)定,這互聯(lián)網(wǎng)還能玩么?

所以,必須有一個統(tǒng)一的規(guī)則,讓大家發(fā)送消息、接收消息的時候有個格式依據(jù),不能隨便寫。

這個規(guī)則就是HTTP協(xié)議,以后瀏覽器發(fā)送請求信息也好,服務(wù)器回復(fù)響應(yīng)信息也罷,都要按照這個規(guī)則來。

HTTP協(xié)議主要規(guī)定了客戶端和服務(wù)器之間的通信格式,那HTTP協(xié)議是怎么規(guī)定消息格式的呢?

讓我們首先打印下我們在服務(wù)端接收到的消息是什么。

import socketsk = socket.socket() sk.bind(("127.0.0.1", 80)) sk.listen()while True:conn, addr = sk.accept()data = conn.recv(8096)print(data) # 將瀏覽器發(fā)來的消息打印出來conn.send(b"OK")conn.close()

輸出:

b'GET / HTTP/1.1\r\nHost: 127.0.0.1:8080\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'

?

然后我們再看一下我們訪問博客園官網(wǎng)時瀏覽器收到的響應(yīng)信息是什么。

響應(yīng)相關(guān)信息可以在瀏覽器調(diào)試窗口的network標(biāo)簽頁中看到。

點(diǎn)擊view source之后顯示如下圖:

?

我們發(fā)現(xiàn)收發(fā)的消息需要按照一定的格式來,這里就需要了解一下HTTP協(xié)議了。

HTTP協(xié)議介紹

HTTP協(xié)議對收發(fā)消息的格式要求

每個HTTP請求和響應(yīng)都遵循相同的格式,一個HTTP包含Header和Body兩部分,其中Body是可選的。 HTTP響應(yīng)的Header中有一個?Content-Type表明響應(yīng)的內(nèi)容格式。如?text/html表示HTML網(wǎng)頁。

HTTP GET請求的格式:

?

HTTP響應(yīng)的格式:

?

?處女版自定義web框架

經(jīng)過上面的補(bǔ)充學(xué)習(xí),我們知道了要想讓我們自己寫的web server端正經(jīng)起來,必須要讓我們的Web server在給客戶端回復(fù)消息的時候按照HTTP協(xié)議的規(guī)則加上響應(yīng)狀態(tài)行,這樣我們就實現(xiàn)了一個正經(jīng)的Web框架了。

import socketsock = 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)# 給回復(fù)的消息加上響應(yīng)狀態(tài)行conn.send(b"HTTP/1.1 200 OK\r\n\r\n")conn.send(b"OK")conn.close()

我們通過十幾行代碼簡單地演示了web 框架的本質(zhì)。

接下來就讓我們繼續(xù)完善我們的自定義web框架吧!

根據(jù)不同的路徑返回不同的內(nèi)容

這樣就結(jié)束了嗎? 如何讓我們的Web服務(wù)根據(jù)用戶請求的URL不同而返回不同的內(nèi)容呢?

小事一樁,我們可以從請求相關(guān)數(shù)據(jù)里面拿到請求URL的路徑,然后拿路徑做一個判斷...

""" 根據(jù)URL中不同的路徑返回不同的內(nèi)容 """import socket sk = socket.socket() sk.bind(("127.0.0.1", 8080)) # 綁定IP和端口 sk.listen() # 監(jiān)聽while 1:# 等待連接conn, add = sk.accept()data = conn.recv(8096) # 接收客戶端發(fā)來的消息# 從data中取到路徑data = str(data, encoding="utf8") # 把收到的字節(jié)類型的數(shù)據(jù)轉(zhuǎn)換成字符串# 按\r\n分割data1 = data.split("\r\n")[0]url = data1.split()[1] # url是我們從瀏覽器發(fā)過來的消息中分離出的訪問路徑conn.send(b'HTTP/1.1 200 OK\r\n\r\n') # 因為要遵循HTTP協(xié)議,所以回復(fù)的消息也要加狀態(tài)行# 根據(jù)不同的路徑返回不同內(nèi)容if url == "/index/":response = b"index"elif url == "/home/":response = b"home"else:response = b"404 not found!"conn.send(response)conn.close()

根據(jù)不同的路徑返回不同的內(nèi)容--函數(shù)版

上面的代碼解決了不同URL路徑返回不同內(nèi)容的需求。

但是問題又來了,如果有很多很多路徑要判斷怎么辦?難道要挨個寫if判斷? 當(dāng)然不用,我們有更聰明的辦法。

""" 根據(jù)URL中不同的路徑返回不同的內(nèi)容--函數(shù)版 """import socket sk = socket.socket() sk.bind(("127.0.0.1", 8080)) # 綁定IP和端口 sk.listen() # 監(jiān)聽# 將返回不同的內(nèi)容部分封裝成函數(shù) def index(url):s = "這是{}頁面!".format(url)return bytes(s, encoding="utf8")def home(url):s = "這是{}頁面!".format(url)return bytes(s, encoding="utf8")while 1:# 等待連接conn, add = sk.accept()data = conn.recv(8096) # 接收客戶端發(fā)來的消息# 從data中取到路徑data = str(data, encoding="utf8") # 把收到的字節(jié)類型的數(shù)據(jù)轉(zhuǎn)換成字符串# 按\r\n分割data1 = data.split("\r\n")[0]url = data1.split()[1] # url是我們從瀏覽器發(fā)過來的消息中分離出的訪問路徑conn.send(b'HTTP/1.1 200 OK\r\n\r\n') # 因為要遵循HTTP協(xié)議,所以回復(fù)的消息也要加狀態(tài)行# 根據(jù)不同的路徑返回不同內(nèi)容,response是具體的響應(yīng)體if url == "/index/":response = index(url)elif url == "/home/":response = home(url)else:response = b"404 not found!"conn.send(response)conn.close()

根據(jù)不同的路徑返回不同的內(nèi)容--函數(shù)進(jìn)階版

看起來上面的代碼還是要挨個寫if判斷,怎么辦?我們還是有辦法!(只要思想不滑坡,方法總比問題多!)

""" 根據(jù)URL中不同的路徑返回不同的內(nèi)容--函數(shù)進(jìn)階版 """import socket sk = socket.socket() sk.bind(("127.0.0.1", 8080)) # 綁定IP和端口 sk.listen() # 監(jiān)聽# 將返回不同的內(nèi)容部分封裝成函數(shù) def index(url):s = "這是{}頁面!".format(url)return bytes(s, encoding="utf8")def home(url):s = "這是{}頁面!".format(url)return bytes(s, encoding="utf8")# 定義一個url和實際要執(zhí)行的函數(shù)的對應(yīng)關(guān)系 list1 = [("/index/", index),("/home/", home), ]while 1:# 等待連接conn, add = sk.accept()data = conn.recv(8096) # 接收客戶端發(fā)來的消息# 從data中取到路徑data = str(data, encoding="utf8") # 把收到的字節(jié)類型的數(shù)據(jù)轉(zhuǎn)換成字符串# 按\r\n分割data1 = data.split("\r\n")[0]url = data1.split()[1] # url是我們從瀏覽器發(fā)過來的消息中分離出的訪問路徑conn.send(b'HTTP/1.1 200 OK\r\n\r\n') # 因為要遵循HTTP協(xié)議,所以回復(fù)的消息也要加狀態(tài)行# 根據(jù)不同的路徑返回不同內(nèi)容func = None # 定義一個保存將要執(zhí)行的函數(shù)名的變量for i in list1:if i[0] == url:func = i[1]breakif func:response = func(url)else:response = b"404 not found!"# 返回具體的響應(yīng)消息conn.send(response)conn.close()

返回具體的HTML文件

完美解決了不同URL返回不同內(nèi)容的問題。 但是我不想僅僅返回幾個字符串,我想給瀏覽器返回完整的HTML內(nèi)容,這又該怎么辦呢?

沒問題,不管是什么內(nèi)容,最后都是轉(zhuǎn)換成字節(jié)數(shù)據(jù)發(fā)送出去的。 我們可以打開HTML文件,讀取出它內(nèi)部的二進(jìn)制數(shù)據(jù),然后再發(fā)送給瀏覽器。

""" 根據(jù)URL中不同的路徑返回不同的內(nèi)容--函數(shù)進(jìn)階版 返回獨(dú)立的HTML頁面 """import socket sk = socket.socket() sk.bind(("127.0.0.1", 8080)) # 綁定IP和端口 sk.listen() # 監(jiān)聽# 將返回不同的內(nèi)容部分封裝成函數(shù) def index(url):# 讀取index.html頁面的內(nèi)容with open("index.html", "r", encoding="utf8") as f:s = f.read()# 返回字節(jié)數(shù)據(jù)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和實際要執(zhí)行的函數(shù)的對應(yīng)關(guān)系 list1 = [("/index/", index),("/home/", home), ]while 1:# 等待連接conn, add = sk.accept()data = conn.recv(8096) # 接收客戶端發(fā)來的消息# 從data中取到路徑data = str(data, encoding="utf8") # 把收到的字節(jié)類型的數(shù)據(jù)轉(zhuǎn)換成字符串# 按\r\n分割data1 = data.split("\r\n")[0]url = data1.split()[1] # url是我們從瀏覽器發(fā)過來的消息中分離出的訪問路徑conn.send(b'HTTP/1.1 200 OK\r\n\r\n') # 因為要遵循HTTP協(xié)議,所以回復(fù)的消息也要加狀態(tài)行# 根據(jù)不同的路徑返回不同內(nèi)容func = None # 定義一個保存將要執(zhí)行的函數(shù)名的變量for i in list1:if i[0] == url:func = i[1]breakif func:response = func(url)else:response = b"404 not found!"# 返回具體的響應(yīng)消息conn.send(response)conn.close()

讓網(wǎng)頁動態(tài)起來

這網(wǎng)頁能夠顯示出來了,但是都是靜態(tài)的啊。頁面的內(nèi)容都不會變化的,我想要的是動態(tài)網(wǎng)站。

沒問題,我也有辦法解決。我選擇使用字符串替換來實現(xiàn)這個需求。(這里使用時間戳來模擬動態(tài)的數(shù)據(jù))

""" 根據(jù)URL中不同的路徑返回不同的內(nèi)容--函數(shù)進(jìn)階版 返回HTML頁面 讓網(wǎng)頁動態(tài)起來 """import socket import timesk = socket.socket() sk.bind(("127.0.0.1", 8080)) # 綁定IP和端口 sk.listen() # 監(jiān)聽# 將返回不同的內(nèi)容部分封裝成函數(shù) def index(url):with open("index.html", "r", encoding="utf8") as f:s = f.read()now = str(time.time())s = s.replace("@@oo@@", now) # 在網(wǎng)頁中定義好特殊符號,用動態(tài)的數(shù)據(jù)去替換提前定義好的特殊符號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和實際要執(zhí)行的函數(shù)的對應(yīng)關(guān)系 list1 = [("/index/", index),("/home/", home), ]while 1:# 等待連接conn, add = sk.accept()data = conn.recv(8096) # 接收客戶端發(fā)來的消息# 從data中取到路徑data = str(data, encoding="utf8") # 把收到的字節(jié)類型的數(shù)據(jù)轉(zhuǎn)換成字符串# 按\r\n分割data1 = data.split("\r\n")[0]url = data1.split()[1] # url是我們從瀏覽器發(fā)過來的消息中分離出的訪問路徑conn.send(b'HTTP/1.1 200 OK\r\n\r\n') # 因為要遵循HTTP協(xié)議,所以回復(fù)的消息也要加狀態(tài)行# 根據(jù)不同的路徑返回不同內(nèi)容func = None # 定義一個保存將要執(zhí)行的函數(shù)名的變量for i in list1:if i[0] == url:func = i[1]breakif func:response = func(url)else:response = b"404 not found!"# 返回具體的響應(yīng)消息conn.send(response)conn.close()

?

好了,在這停頓...

服務(wù)器程序和應(yīng)用程序

對于真實開發(fā)中的python web程序來說,一般會分為兩部分:服務(wù)器程序和應(yīng)用程序。

服務(wù)器程序負(fù)責(zé)對socket服務(wù)器進(jìn)行封裝,并在請求到來時,對請求的各種數(shù)據(jù)進(jìn)行整理。

應(yīng)用程序則負(fù)責(zé)具體的邏輯處理。為了方便應(yīng)用程序的開發(fā),就出現(xiàn)了眾多的Web框架,例如:Django、Flask、web.py 等。不同的框架有不同的開發(fā)方式,但是無論如何,開發(fā)出的應(yīng)用程序都要和服務(wù)器程序配合,才能為用戶提供服務(wù)。

?

這樣,服務(wù)器程序就需要為不同的框架提供不同的支持。這樣混亂的局面無論對于服務(wù)器還是框架,都是不好的。對服務(wù)器來說,需要支持各種不同框架,對框架來說,只有支持它的服務(wù)器才能被開發(fā)出的應(yīng)用使用。

這時候,標(biāo)準(zhǔn)化就變得尤為重要。我們可以設(shè)立一個標(biāo)準(zhǔn),只要服務(wù)器程序支持這個標(biāo)準(zhǔn),框架也支持這個標(biāo)準(zhǔn),那么他們就可以配合使用。一旦標(biāo)準(zhǔn)確定,雙方各自實現(xiàn)。這樣,服務(wù)器可以支持更多支持標(biāo)準(zhǔn)的框架,框架也可以使用更多支持標(biāo)準(zhǔn)的服務(wù)器。

WSGI(Web Server Gateway Interface)就是一種規(guī)范,它定義了使用Python編寫的web應(yīng)用程序與web服務(wù)器程序之間的接口格式,實現(xiàn)web應(yīng)用程序與web服務(wù)器程序間的解耦。

常用的WSGI服務(wù)器有uwsgi、Gunicorn。而Python標(biāo)準(zhǔn)庫提供的獨(dú)立WSGI服務(wù)器叫wsgiref,Django開發(fā)環(huán)境用的就是這個模塊來做服務(wù)器。

?

從這繼續(xù)...

wsgiref

我們利用wsgiref模塊來替換我們自己寫的web框架的socket server部分:

""" 根據(jù)URL中不同的路徑返回不同的內(nèi)容--函數(shù)進(jìn)階版 返回HTML頁面 讓網(wǎng)頁動態(tài)起來 wsgiref模塊版 """import time from wsgiref.simple_server import make_server# 將返回不同的內(nèi)容部分封裝成函數(shù) 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和實際要執(zhí)行的函數(shù)的對應(yīng)關(guān)系 list1 = [("/index/", index),("/home/", home), ]def run_server(environ, start_response):start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ]) # 設(shè)置HTTP響應(yīng)的狀態(tài)碼和頭信息url = environ['PATH_INFO'] # 取到用戶輸入的urlfunc = Nonefor i in list1:if i[0] == url:func = i[1]breakif 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

上面的代碼實現(xiàn)了一個簡單的動態(tài),我完全可以從數(shù)據(jù)庫中查詢數(shù)據(jù),然后去替換我html中的對應(yīng)內(nèi)容,然后再發(fā)送給瀏覽器完成渲染。 這個過程就相當(dāng)于HTML模板渲染數(shù)據(jù)。 本質(zhì)上就是HTML內(nèi)容中利用一些特殊的符號來替換要展示的數(shù)據(jù)。 我這里用的特殊符號是我定義的,其實模板渲染有個現(xiàn)成的工具:?jinja2

下載jinja2:

pip install jinja2

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
</head>
<body>
<h1>姓名:{{name}}</h1>
<h1>愛好:</h1>
<ul>
{% for hobby in hobby_list %}
<li>{{hobby}}</li>
{% endfor %}
</ul>
</body>
</html>

index2.html文件

<!DOCTYPE html> <html lang="zh-CN"> <head><meta charset="UTF-8"><meta http-equiv="x-ua-compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Title</title> </head> <body><h1>姓名:{{name}}</h1><h1>愛好:</h1><ul>{% for hobby in hobby_list %}<li>{{hobby}}</li>{% endfor %}</ul> </body> </html>

使用jinja2渲染index2.html文件:

from wsgiref.simple_server import make_server from jinja2 import Templatedef index():with open("index2.html", "r") as f:data = f.read()template = Template(data) # 生成模板文件ret = template.render({"name": "Alex", "hobby_list": ["燙頭", "泡吧"]}) # 把數(shù)據(jù)填充到模板里面return [bytes(ret, encoding="utf8"), ]def home():with open("home.html", "rb") as f:data = f.read()return [data, ]# 定義一個url和函數(shù)的對應(yīng)關(guān)系 URL_LIST = [("/index/", index),("/home/", home), ]def run_server(environ, start_response):start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ]) # 設(shè)置HTTP響應(yīng)的狀態(tài)碼和頭信息url = environ['PATH_INFO'] # 取到用戶輸入的urlfunc = None # 將要執(zhí)行的函數(shù)for i in URL_LIST:if i[0] == url:func = i[1] # 去之前定義好的url列表里找url應(yīng)該執(zhí)行的函數(shù)breakif func: # 如果能找到要執(zhí)行的函數(shù)return func() # 返回函數(shù)的執(zhí)行結(jié)果else:return [bytes("404沒有該頁面", encoding="utf8"), ]if __name__ == '__main__':httpd = make_server('', 8000, run_server)print("Serving HTTP on port 8000...")httpd.serve_forever()

現(xiàn)在的數(shù)據(jù)是我們自己手寫的,那可不可以從數(shù)據(jù)庫中查詢數(shù)據(jù),來填充頁面呢?

使用pymysql連接數(shù)據(jù)庫:

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()

創(chuàng)建一個測試的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的語法規(guī)則寫上,其內(nèi)部就會按照指定的語法進(jìn)行相應(yīng)的替換,從而達(dá)到動態(tài)的返回內(nèi)容。

Django

Django官網(wǎng)下載頁面

安裝(安裝最新LTS版):

pip3 install django==1.11.9

創(chuàng)建一個django項目:

下面的命令創(chuàng)建了一個名為"mysite"的Django 項目:

django-admin startproject mysite

目錄介紹:

mysite/ ├── manage.py # 管理文件 └── mysite # 項目目錄├── __init__.py├── settings.py # 配置├── urls.py # 路由 --> URL和函數(shù)的對應(yīng)關(guān)系└── wsgi.py # runserver命令就使用wsgiref模塊做簡單的web server

運(yùn)行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',],},}, ]

靜態(tài)文件配置:

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

看不明白?有圖有真相:

剛開始學(xué)習(xí)時可在配置文件中暫時禁用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', ]

Django基礎(chǔ)必備三件套:

from django.shortcuts import HttpResponse, render, redirect

HttpResponse

內(nèi)部傳入一個字符串參數(shù),返回給瀏覽器。

例如:

def index(request):# 業(yè)務(wù)邏輯代碼return HttpResponse("OK")

render

除request參數(shù)外還接受一個待渲染的模板文件和一個保存具體數(shù)據(jù)的字典參數(shù)。

將數(shù)據(jù)填充進(jìn)模板文件,最后把結(jié)果返回給瀏覽器。(類似于我們上面用到的jinja2)

例如:

def index(request):# 業(yè)務(wù)邏輯代碼return render(request, "index.html", {"name": "alex", "hobby": ["燙頭", "泡吧"]})

redirect

接受一個URL參數(shù),表示跳轉(zhuǎn)到指定的URL。

例如:

def index(request):# 業(yè)務(wù)邏輯代碼return redirect("/home/")

重定向是怎么回事?

?

?

課后練習(xí):

Django版登錄

啟動Django報錯:

Django 啟動時報錯 “UnicodeEncodeError ...”

報這個錯誤通常是因為計算機(jī)名為中文,改成英文的計算機(jī)名重啟下電腦就可以了。

?Django 啟動報錯“SyntaxError: Generator expression must be parenthesized”

報這個錯很大可能是因為使用了Python3.7.0,而目前(2018-06-12)Python3.7.0和Django還有點(diǎn)兼容性問題,換回Python3.6的環(huán)境即可。

轉(zhuǎn)載于:https://www.cnblogs.com/xyhh/p/10836545.html

總結(jié)

以上是生活随笔為你收集整理的Web框架本质的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。