1、Web框架的本質
1、本質
實際上Web應用本質上就是一個socket服務端,
而用戶的瀏覽器就是一個socket客戶端。
2、最原始的web框架
socket服務端
import socket
sk = socket.socket()
sk.bind(("127.0.0.1", 80))
sk.listen()
while True:
conn, addr = sk.accept()
data = conn.recv(5120)
print(data) # 打印一下接收到的數據是什麼
conn.send(b"Hello World")
conn.close()
上面這幾行代碼就是最基礎的web框架的服務端,
用戶使用瀏覽器輸入網址(IP),就會給服務端發送請求消息,
好比你在瀏覽器輸入上面服務器的ip地址 127.0.0.1:80
瀏覽器就會幫你給服務端發送請求消息,服務端就能夠接收到你的請求消息,
並對此能夠作出相應的操做。
固然了,雖然上面的代碼是web框架的本質,可是還不能進行消息的響應,爲何呢?
由於沒有一個統一的規則啊,你想一想若是每一個人的網站都按照本身的意願隨便定製規則,
那瀏覽器不就崩了?
因此必須有一個統一的規則,讓你們發送消息、接收消息的時候有個格式依據,不能隨便寫。
這個規則就是HTTP協議,之後瀏覽器發送請求信息也好,服務器回覆響應信息也罷,都要按照這個規則來進行
如今去看一眼剛纔收到的data數據是什麼(客戶端的請求數據)
b'GET /index/ 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/69.0.3497.92 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n'
而後能夠再看一眼平時咱們訪問百度時瀏覽器接收到的響應信息
HTTP/1.1 301 Moved Permanently
Date: Wed, 24 Oct 2018 07:06:00 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 147
Location: https://www.cnblogs.com/
X-UA-Compatible: IE=10
X-Frame-Options: SAMEORIGIN
這樣看起來,好像找不出什麼規則,那就先了解一下HTTP協議(上一篇博客),在回來看看是否發現什麼規則

HTTP協議對收發消息的格式要求:
每一個HTTP請求和響應都遵循相同的格式,一個HTTP包含Header和Body兩部分,其中Body是可選的(就是能夠不寫)。
HTTP響應的Header中有一個 Content-Type代表響應的內容格式。如 text/html表示HTML網頁。
那麼上面的請求數據data,咱們也能夠給它分出Header和Body兩部分(\r\n表明回車換行),以下:
GET /index/ HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
請求數據
因此咱們想要開始那段代碼能順利給客戶端返回消息,咱們也按照HTTP協議進行發送就行了
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',80))
sk.listen()
while True:
conn,addr = sk.accept()
data = conn.recv(5120)
print(data)
conn.send(b'HTTP/1.1 200 OK\r\n\r\nHello World') # HTTP/1.1 200 OK\r\n\r\n 是響應頭部爲空,響應正文爲Hello World的HTTP響應格式
conn.close()
這個時候你在瀏覽器輸入127.0.0.1:80就能夠收到服務端給你返回的消息了
3、服務器例子
1、根據不一樣的路徑返回不一樣的內容
注意:咱們服務器接收到的請求數據全是bytes類型的,回車換行是用\r\n表示的
原始請求數據:b'GET /index/ 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/69.0.3497.92 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n'
"""
Web框架原理:
根據不一樣的URL返回不一樣的內容
1. 先拿到用戶訪問的URL是什麼
2. 返回不一樣的內容
"""
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()
while 1:
conn, addr = sk.accept()
# socket收到的消息是bytes類型的
data = conn.recv(5120)
# 從請求的消息中拿到請求的URL是什麼
data_str = data.decode('utf8')
# 按照\r\n分割字符串
list1 = data_str.split('\r\n')
# url在第一個元素裏面再進行分割取到
url = list1[0].split()[1]
# 對不一樣的url返回不一樣的消息
if url == '/index/':
msg = 'This is index page'
elif url == '/home/':
msg = 'This is home page'
else:
msg = '404 Not Found'
conn.send(b'HTTP/1.1 200 OK\r\n\r\n') # 先發送響應行
conn.send(msg.encode('utf8'))
conn.close()
此時你在瀏覽器輸入:
http://127.0.0.1:8080 ---> 404 Not Found
http://127.0.0.1:8080/index/ ---> This is index page
http://127.0.0.1:8080/home/ ---> This is home page
2、根據不一樣的路徑返回不一樣的內容函數版
"""
Web框架原理:
根據不一樣的URL返回不一樣的內容函數版
1. 先拿到用戶訪問的URL是什麼
2. 返回不一樣的內容
"""
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()
# 定義處理用戶請求的函數
def index(url):
s = '你訪問的是%s頁面' %url
return s.encode('utf8')
def home(url):
s = '你訪問的是%s頁面' %url
return s.encode('utf8')
while 1:
conn, addr = sk.accept()
# socket收到的消息是bytes類型的
data = conn.recv(5120)
# 從請求的消息中拿到請求的URL是什麼
data_str = data.decode('utf8')
# 按照\r\n分割字符串
list1 = data_str.split('\r\n')
# url在第一個元素裏面再進行分割取到
url = list1[0].split()[1]
# 對不一樣的url返回不一樣的消息
if url == '/index/':
msg = index(url)
elif url == '/home/':
msg = home(url)
else:
msg = b'404 Not Found'
# 由於有中文,全部要在響應頭部添加Content-Type: text/html; charset=utf-8
conn.send(b'HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n') # 先發送響應行
conn.send(msg)
conn.close()
3、根據不一樣的路徑返回不一樣的內容函數進階版
"""
Web框架原理:
根據不一樣的URL返回不一樣的內容函數進階版
1. 先拿到用戶訪問的URL是什麼
2.設置一個url和函數的對應關係
3. 根據對應關係返回不一樣的內容
"""
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()
# 定義處理用戶請求的函數
def index(url):
s = '你訪問的是%s頁面' %url
return s.encode('utf8')
def home(url):
s = '你訪問的是%s頁面' %url
return s.encode('utf8')
# 定義一個用戶訪問的url和要執行的函數的對應關係
url_func = [
('/index/', index),
('/home/', home)
]
while 1:
conn, addr = sk.accept()
# socket收到的消息是bytes類型的
data = conn.recv(5120)
# 從請求的消息中拿到請求的URL是什麼
data_str = data.decode('utf8')
# 按照\r\n分割字符串
list1 = data_str.split('\r\n')
# url在第一個元素裏面再進行分割取到
url = list1[0].split()[1]
# 循環url列表,對不一樣的url返回不一樣的消息
func = None
for i in url_func:
if i[0] == url:
func = i[1]
break
if func:
msg = func(url)
else:
msg = b'404 Not Found'
# 由於有中文,全部要在響應頭部添加Content-Type: text/html; charset=utf-8
conn.send(b'HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n') # 先發送響應行
conn.send(msg)
conn.close()
4、返回具體的html頁面
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()
# 定義處理用戶請求的函數
def index(url):
s = '你訪問的是%s頁面' %url
return s.encode('utf8')
def home(url):
s = '你訪問的是%s頁面' %url
return s.encode('utf8')
def table(url):
# 返回TableOp.html
with open('TableOp.html', mode='rb') as f:
return f.read()
# 定義一個用戶訪問的url和要執行的函數的對應關係
url_func = [
('/index/', index),
('/home/', home),
('/table/',table)
]
while 1:
conn, addr = sk.accept()
# socket收到的消息是bytes類型的
data = conn.recv(5120)
# 從請求的消息中拿到請求的URL是什麼
data_str = data.decode('utf8')
# 按照\r\n分割字符串
list1 = data_str.split('\r\n')
# url在第一個元素裏面再進行分割取到
url = list1[0].split()[1]
# 循環url列表,對不一樣的url返回不一樣的消息
func = None
for i in url_func:
if i[0] == url:
func = i[1]
break
if func:
msg = func(url)
else:
msg = b'404 Not Found'
# 由於有中文,全部要在響應頭部添加Content-Type: text/html; charset=utf-8
conn.send(b'HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n') # 先發送響應行
conn.send(msg)
conn.close()
5、返回動態的html頁面
"""
由於時間是會動的,因此這裏用時間戳表明動態的事件
"""
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>這是index頁面!</h1>
<p>如今的時間是:@t@</p>
</body>
</html>
index頁面代碼
import time
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()
# 定義處理用戶請求的函數
def index(url):
with open('index.html', 'r', encoding='utf8') as f1:
html_s = f1.read()
# 根據用戶不一樣,取出不一樣的數據
# 用不一樣的數據去替換頁面上的特殊符號
now = str(time.strftime("%H:%M:%S"))
msg = html_s.replace('@t@', now)
return msg.encode('utf8')
def home(url):
s = '你訪問的是%s頁面' %url
return s.encode('utf8')
def table(url):
# 返回TableOp.html
with open('TableOp.html', mode='rb') as f:
return f.read()
# 定義一個用戶訪問的url和要執行的函數的對應關係
url_func = [
('/index/', index),
('/home/', home),
('/table/', table)
]
while 1:
conn, addr = sk.accept()
# socket收到的消息是bytes類型的
data = conn.recv(5120)
# 從請求的消息中拿到請求的URL是什麼
data_str = data.decode('utf8')
# 按照\r\n分割字符串
list1 = data_str.split('\r\n')
# url在第一個元素裏面再進行分割取到
url = list1[0].split()[1]
# 循環url列表,對不一樣的url返回不一樣的消息
func = None
for i in url_func:
if i[0] == url:
func = i[1]
break
if func:
msg = func(url)
else:
msg = b'404 Not Found'
# 由於有中文,全部要在響應頭部添加Content-Type: text/html; charset=utf-8
conn.send(b'HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n') # 先發送響應行
conn.send(msg)
conn.close()
2、服務器程序和應用程序
1、本質介紹
對於真實開發中的python web程序來講,通常會分爲兩部分:服務器程序和應用程序,而後經過一個協議鏈接起來,以下:
收發socket消息(Web服務器程序) --> uWsgi、Gunicorn、wsgiref (Nginx和tomcat)
WSGI協議
業務邏輯不一樣(Web應用程序) --> Django、Flask、Webpy、bottle、Tornado
服務器程序負責對socket服務器進行封裝,並在請求到來時,對請求的各類數據進行整理。
應用程序則負責具體的邏輯處理。爲了方便應用程序的開發,就出現了衆多的Web框架,例如:Django、Flask、web.py 等。不一樣的框架有不一樣的開發方式,可是不管如何,開發出的應用程序都要和服務器程序配合,才能爲用戶提供服務。
這樣,服務器程序就須要爲不一樣的框架提供不一樣的支持。這樣混亂的局面不管對於服務器仍是框架,都是很差的。對服務器來講,須要支持各類不一樣框架,對框架來講,只有支持它的服務器才能被開發出的應用使用。
這時候,標準化就變得尤其重要。咱們能夠設立一個標準,只要服務器程序支持這個標準,框架也支持這個標準,那麼他們就能夠配合使用。一旦標準肯定,雙方各自實現。這樣,服務器能夠支持更多支持標準的框架,框架也可使用更多支持標準的服務器。
WSGI(Web Server Gateway Interface)就是一種規範,它定義了使用Python編寫的web應用程序與web服務器程序之間的接口格式,實現web應用程序與web服務器程序間的解耦。
經常使用的WSGI服務器有uwsgi、Gunicorn。而Python標準庫提供的獨立WSGI服務器叫wsgiref,Django開發環境用的就是這個模塊來作服務器。
Python中Web框架的分類
a. 收發socket消息
b. 根據不一樣的URL執行不一樣的函數(業務邏輯)
c. 字符串替換(動態網頁)
1. 第一種分類:(按照上面的三部分功能劃分)
1. 本身實現b和c,使用第三方的a --> Django
2. 本身實現b,使用第三方的a和c --> Flask
3. 本身實現a、b、c --> Tornado
2. 第二種分類:
1. Django(大而全)
2. 其餘
2、例子
1、wsgiref版web開發
"""
利用wsgiref模塊來替換咱們本身寫的web框架的socket server部分
"""
import time
from wsgiref.simple_server import make_server
# 定義處理用戶請求的函數
def index(url):
with open('index.html', 'r', encoding='utf8') as f1:
html_s = f1.read()
# 根據用戶不一樣,取出不一樣的數據
# 用不一樣的數據去替換頁面上的特殊符號
now = str(time.strftime("%H:%M:%S"))
msg = html_s.replace('@t@', now)
return msg.encode('utf8')
def home(url):
s = '你訪問的是%s頁面' %url
return s.encode('utf8')
def table(url):
# 返回TableOp.html
with open('TableOp.html', mode='rb') as f:
return f.read()
# 定義一個用戶訪問的url和要執行的函數的對應關係
url_func = [
('/index/', index),
('/home/', home),
('/table/', table)
]
# wsgiref模塊的格式要求
def run_server(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ]) # 設置HTTP響應的狀態碼和頭信息
url = environ['PATH_INFO'] # 取到用戶輸入的url
# 循環url列表,對不一樣的url返回不一樣的消息
func = None
for i in url_func:
if i[0] == url:
func = i[1]
break
if func:
msg = func(url)
else:
msg = b'404 Not Found'
return [msg]
if __name__ == '__main__':
httpd = make_server('127.0.0.1', 8080, run_server)
httpd.serve_forever()
二、wsgiref+jinja2版web開發
上面的代碼實現了一個簡單的動態,我徹底能夠從數據庫中查詢數據,而後去替換我html中的對應內容,而後再發送給瀏覽器完成渲染。 這個過程就至關於HTML模板渲染數據。
本質上就是HTML內容中利用一些特殊的符號來替換要展現的數據。 我這裏用的特殊符號是我定義的,其實模板渲染有個現成的工具: jinja2
下載jinja2:在cmd命令行輸入 pip install jinja2 安裝第三方包
"""
利用wsgiref和jinja2模塊動態渲染userinfo頁面
"""
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>用戶列表</title>
</head>
<body>
<table border="1">
<thead>
<tr>
<th>id值</th>
<th>姓名</th>
<th>密碼</th>
</tr>
</thead>
<tbody>
{% for user in user_dict %}
<tr>
<td>{{user.id}}</td>
<td>{{user.username}}</td>
<td>{{user.password}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
userinfo代碼
import time
import pymysql
from wsgiref.simple_server import make_server
from jinja2 import Template
# 定義處理用戶請求的函數
def index(url):
with open('index.html', 'r', encoding='utf8') as f1:
html_s = f1.read()
# 根據用戶不一樣,取出不一樣的數據
# 用不一樣的數據去替換頁面上的特殊符號
now = str(time.strftime("%H:%M:%S"))
msg = html_s.replace('@t@', now)
return msg.encode('utf8')
def home(url):
s = '你訪問的是%s頁面' %url
return s.encode('utf8')
def table(url):
# 返回TableOp.html
with open('TableOp.html', mode='rb') as f:
return f.read()
def userinfo(url):
# 1. 鏈接數據庫,把全部的用戶數據拿到
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='123abc',
database='userinfo',
charset='utf8'
)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute('select * from userinfo;')
# 從數據庫中拿到的數據user_dict
user_dict = cursor.fetchall()
with open('userinfo.html','r',encoding='utf8') as f:
data = f.read()
# 讀取網頁內容,生成jinja2模板對象
template = Template(data)
# 讓jinja2用數據替換HTML中的特殊符號,拿到新的html內容並返回
msg = template.render({'user_dict':user_dict})
return bytes(msg, encoding="utf8")
# 定義一個用戶訪問的url和要執行的函數的對應關係
url_func = [
('/index/', index),
('/home/', home),
('/table/', table),
('/userinfo/', userinfo)
]
# wsgiref模塊的格式要求
def run_server(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ]) # 設置HTTP響應的狀態碼和頭信息
url = environ['PATH_INFO'] # 取到用戶輸入的url
# 循環url列表,對不一樣的url返回不一樣的消息
func = None
for i in url_func:
if i[0] == url:
func = i[1]
break
if func:
msg = func(url)
else:
msg = b'404 Not Found'
return [msg]
if __name__ == '__main__':
httpd = make_server('127.0.0.1', 8080, run_server)
httpd.serve_forever()
3、Django初識
1、安裝
命令安裝:pip install django==1.11.16
PyCharm安裝:
2、建立一個django項目
命令行建立:django-admin startproject first_django(項目名)
PyCharm建立:File -> new project -> Django --> 右邊填項目名而且選擇Python解釋器
三、Django app
切換到項目目錄下
命令行建立:python manage.py startapp appName
PyCharm建立:File --> new project --> Django --> More Settings --> Application name
4、運行Django項目
命令行
切換到項目的目錄下
python manage.py runserver # 默認8000端口
python manage.py runserver 127.0.0.1:8080 # 能夠本身設置ip和端口
python manage.py runserver 8090 # 也能夠只設置端口,ip默認是本地ip127.0.0.1
PyCharm
點綠色的三角(注意左側名稱要與項目名相同)
5、目錄介紹
first_django/
├── manage.py # 管理文件
└── first_django # 項目目錄
├── __init__.py
├── settings.py # 配置文件
├── urls.py # 路由 --> URL和函數的對應關係
└── wsgi.py # runserver命令就使用wsgiref模塊作簡單的web server

4、django基礎
# urls.py
from django.shortcuts import HttpResponse, render, redirect
1、HttpResponse
內部傳入一個字符串參數,返回給瀏覽器。
例如:
def index(request):
# request: 表示全部和請求相關的數據都封裝在這個參數裏面(固定傳入這個參數)
# HttpResponse:
# 按照HTTP協議的格式返回
return HttpResponse("OK")
2、render
返回一個html頁面
除request參數外還接受一個待渲染的模板文件和一個保存具體數據的字典參數。
將數據填充進模板文件,最後把結果返回給瀏覽器。(相似於咱們上面用到的jinja2)
例如:無參數時,表示打開這個網頁並返回給客戶端 def meun(request):
# render:
# 1. 找到那個html文件
# 2. 讀取文件內容
# 3. 按照HTTP協議的格式返回
return render(request, "meun.html")
有參數時,表明打開這個網頁,並用這個參數(字典)去替換網頁內的特殊字符,而後返回給客戶端
def meun(request):
# 找到那個html文件
# 讀取文件內容
# 用參數去替換文件內的特殊字符
# 按照http協議的格式返回
rerurn render(request,'meun.html',{"name":"ming","age":18})
3、redirect
重定向
接受一個URL參數,表示跳轉到指定的URL。
例如:
def home(request):
# 業務邏輯代碼
return redirect("/index/")
5、啓動Django報錯
Django 啓動時報錯 「UnicodeEncodeError ...」
報這個錯誤一般是由於計算機名爲中文,改爲英文的計算機名重啓下電腦就能夠了。
Django 啓動報錯「SyntaxError: Generator expression must be parenthesized」
報這個錯很大多是由於使用了Python3.7.0,而目前(2018-06-12)Python3.7.0和Django還有點兼容性問題,換回Python3.6的環境便可。
6、urls.py
主要是寫頁面與函數的對應關係,好比
from django.conf.urls import url
from django.contrib import admin
from django.shortcuts import HttpResponse,render,redirect # 導入django的模塊
def index(request):
# request: 表示全部和請求相關的數據都封裝在這個參數裏面(固定傳入這個參數)
# HttpResponse:
# 按照HTTP協議的格式返回
return HttpResponse('OK')
def meun(request):
# render:
# 1. 找到那個html文件
# 2. 讀取文件內容
# 3. 按照HTTP協議的格式返回
return render(request, "meun.html")
def dashboard(request):
return render(request,'Dashboard.html')
def home(request):
# 業務邏輯代碼
return redirect("/index/")
urlpatterns = [ # 這裏寫頁面和函數的對應關係,前面是你在瀏覽器輸入的頁面url,後面是你要定義的函數
url(r'^admin/', admin.site.urls),
url(r'^index/',index),
url(r'^meun/',meun),
url(r'^Dashboard/',dashboard),
url(r'^home/',home),
]
7、settings.py簡單分析
# 項目的起始路徑
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 你自定義的app都要在這裏註冊
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'appName.apps.AppnameConfig',
]
# 全部和HTML文件相關的配置
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')] # 告訴Django框架去哪裏找HTML文件,因此htnl頁面應該放在templates目錄裏面
,
'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/是下面STATICFILES_DIRS裏面全部路徑的別名(這裏/static/就能夠表明mystatic的路徑)
# 所以你要引用什麼靜態文件。好比css、js文件等都要在路徑前添加/static/
STATIC_URL = '/static/'
# 固定的配置項,告訴Django框架個人靜態文件保存在哪些目錄下
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'mystatic')
]
8、request
一、request.POST
經過POST方法提交給服務器的數據都會存在request.POST裏面,request.POST是一個相似於字典的類型,取值方法跟字典同樣,能夠根據鍵去取值,也能夠經過get方法,例如:
request.POST["name"] # 拿到鍵爲name的數據
request.POST.get("name",None) # 拿到鍵爲name的數據,若這個數據不存在,則返回None
二、request.method
request.method就是獲取客戶端提交數據的方式(POST、GET等)
9、總結
Django基礎 建立Django項目的步驟
1. PyCharm或者命令行建立一個Django項目
django-admin startproject 項目名
2. 建立一個初始的app,而且在settings.py中告訴Django
python manage.py startapp app的名字
3. 檢查settings.py 專門存放HTML文件的Templates配置項
4. 配置靜態文件相關
1. STATIC_URL = '/static/'
2. STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
3. 在項目的根目錄建立一個用來存放靜態文件的static目錄
5. 註釋csrf相關的那一行(大概在46行)
不然表單沒辦法提交數據,就會提示Forbidden 403的錯誤