生活随笔
收集整理的這篇文章主要介紹了
django之视图
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
視圖
- 視圖接受Web請求并且返回Web響應
- 視圖就是一個python函數,被定義在views.py中
- 響應可以是一張網頁的HTML內容,一個重定向,一個404錯誤等等
- 響應處理過程如下圖:
URLconf
- 在settings.py文件中通過ROOT_URLCONF指定根級url的配置
- urlpatterns是一個url()實例的列表
- 一個url()對象包括:
- 編寫URLconf的注意:
- 若要從url中捕獲一個值,需要在它周圍設置一對圓括號
- 不需要添加一個前導的反斜杠,如應該寫作'test/',而不應該寫作'/test/'
- 每個正則表達式前面的r表示字符串不轉義
- 請求的url被看做是一個普通的python字符串,進行匹配時不包括get或post請求的參數及域名
http://www.itcast.cn/python/1/?i=1&p=new,只匹配“/python/1/”部分
url(r
'^([0-9]+)/$', views.detail, name=
'detail'),
- 正則表達式命名組,通過關鍵字參數傳遞給視圖,本例中關鍵字參數為id
url(r
'^(?P<id>[0-9]+)/$', views.detail, name=
'detail'),?
- 參數匹配規則:優先使用命名參數,如果沒有命名參數則使用位置參數
- 每個捕獲的參數都作為一個普通的python字符串傳遞給視圖
- 性能:urlpatterns中的每個正則表達式在第一次訪問它們時被編譯,這使得系統相當快
包含其它的URLconfs
- 在應用中創建urls.py文件,定義本應用中的urlconf,再在項目的settings中使用include()
from django.conf.urls
import include, url
urlpatterns =
[url(r'^', include(
'booktest.urls', namespace=
'booktest')),
] - 匹配過程:先與主URLconf匹配,成功后再用剩余的部分與應用中的URLconf匹配
請求http://www.itcast.cn/booktest/1/
在sesstings.py中的配置:
url(r'^booktest/', include(
'booktest.urls', namespace=
'booktest')),
在booktest應用urls.py中的配置
url(r'^([0-9]+)/$', views.detail, name=
'detail'),
匹配部分是:/booktest/1/
匹配過程:在settings.py中與“booktest/”成功,再用“1/”與booktest應用的urls匹配
- 使用include可以去除urlconf的冗余
- 參數:視圖會收到來自父URLconf、當前URLconf捕獲的所有參數
- 在include中通過namespace定義命名空間,用于反解析
URL的反向解析
- 如果在視圖、模板中使用硬編碼的鏈接,在urlconf發生改變時,維護是一件非常麻煩的事情
- 解決:在做鏈接時,通過指向urlconf的名稱,動態生成鏈接地址
- 視圖:使用django.core.urlresolvers.reverse()函數
- 模板:使用url模板標簽
定義視圖
- 本質就是一個函數
- 視圖的參數
- 一個HttpRequest實例
- 通過正則表達式組獲取的位置參數
- 通過正則表達式組獲得的關鍵字參數
- 在應用目錄下默認有views.py文件,一般視圖都定義在這個文件中
- 如果處理功能過多,可以將函數定義到不同的py文件中
新建views1.py
#coding:utf-8
from django.http
import HttpResponse
def index(request):return HttpResponse(
"你好")在urls.py中修改配置
from .
import views1
url(r'^$', views1.index, name=
'index'),
錯誤視圖
- Django原生自帶幾個默認視圖用于處理HTTP錯誤
404 (page not found) 視圖
- defaults.page_not_found(request, template_name='404.html')
- 默認的404視圖將傳遞一個變量給模板:request_path,它是導致錯誤的URL
- 如果Django在檢測URLconf中的每個正則表達式后沒有找到匹配的內容也將調用404視圖
- 如果在settings中DEBUG設置為True,那么將永遠不會調用404視圖,而是顯示URLconf 并帶有一些調試信息
- 在templates中創建404.html
<!DOCTYPE html>
<html>
<head><title></title>
</head>
<body>
找不到了
<hr/>
{{request_path}}
</body>
</html>
DEBUG =
False
ALLOWED_HOSTS = [
'*', ]
http://127.0.0.1:8000/test/?
500 (server error) 視圖
- defaults.server_error(request, template_name='500.html')
- 在視圖代碼中出現運行時錯誤
- 默認的500視圖不會傳遞變量給500.html模板
- 如果在settings中DEBUG設置為True,那么將永遠不會調用505視圖,而是顯示URLconf 并帶有一些調試信息
400 (bad request) 視圖
- defaults.bad_request(request, template_name='400.html')
- 錯誤來自客戶端的操作
- 當用戶進行的操作在安全方面可疑的時候,例如篡改會話cookie
HttpReqeust對象
- 服務器接收到http協議的請求后,會根據報文創建HttpRequest對象
- 視圖函數的第一個參數是HttpRequest對象
- 在django.http模塊中定義了HttpRequest對象的API
屬性
- 下面除非特別說明,屬性都是只讀的
- path:一個字符串,表示請求的頁面的完整路徑,不包含域名
- method:一個字符串,表示請求使用的HTTP方法,常用值包括:'GET'、'POST'
- encoding:一個字符串,表示提交的數據的編碼方式
- 如果為None則表示使用瀏覽器的默認設置,一般為utf-8
- 這個屬性是可寫的,可以通過修改它來修改訪問表單數據使用的編碼,接下來對屬性的任何訪問將使用新的encoding值
- GET:一個類似于字典的對象,包含get請求方式的所有參數
- POST:一個類似于字典的對象,包含post請求方式的所有參數
- FILES:一個類似于字典的對象,包含所有的上傳文件
- COOKIES:一個標準的Python字典,包含所有的cookie,鍵和值都為字符串
- session:一個既可讀又可寫的類似于字典的對象,表示當前的會話,只有當Django 啟用會話的支持時才可用,詳細內容見“狀態保持”
方法
- is_ajax():如果請求是通過XMLHttpRequest發起的,則返回True
QueryDict對象
- 定義在django.http.QueryDict
- request對象的屬性GET、POST都是QueryDict類型的對象
- 與python字典不同,QueryDict類型的對象用來處理同一個鍵帶有多個值的情況
- 方法get():根據鍵獲取值
- 只能獲取鍵的一個值
- 如果一個鍵同時擁有多個值,獲取最后一個值
dict.get(
'鍵',default)
或簡寫為
dict['鍵']
dict.getlist(
'鍵',default)
GET屬性
- QueryDict類型的對象
- 包含get請求方式的所有參數
- 與url請求地址中的參數對應,位于?后面
- 參數的格式是鍵值對,如key1=value1
- 多個參數之間,使用&連接,如key1=value1&key2=value2
- 鍵是開發人員定下來的,值是可變的
- 示例如下
- 創建視圖getTest1用于定義鏈接,getTest2用于接收一鍵一值,getTest3用于接收一鍵多值
def getTest1(request):return render(request,
'booktest/getTest1.html')
def getTest2(request):return render(request,
'booktest/getTest2.html')
def getTest3(request):return render(request,
'booktest/getTest3.html')
url(r
'^getTest1/$', views.getTest1),
url(r'^getTest2/$', views.getTest2),
url(r'^getTest3/$', views.getTest3),
<html>
<head><title>Title</title>
</head>
<body>
鏈接1:一個鍵傳遞一個值
<a href=
"/getTest2/?a=1&b=2">gettest2</a><br>
鏈接2:一個鍵傳遞多個值
<a href=
"/getTest3/?a=1&a=2&b=3">gettest3</a>
</body>
</html>
def getTest2(request):a=request.GET[
'a']b=request.GET[
'b']context={
'a':a,
'b':b}return render(request,
'booktest/getTest2.html',context)
<html>
<head><title>Title</title>
</head>
<body>
a:{{ a }}<br>
b:{{ b }}
</body>
</html>
def getTest3(request):a=request.GET.getlist(
'a')b=request.GET[
'b']context={
'a':a,
'b':b}return render(request,
'booktest/getTest3.html',context)
<html>
<head><title>Title</title>
</head>
<body>
a:{%
for item
in a %
}
{{ item }}
{% endfor %
}
<br>
b:{{ b }}
</body>
</html>
POST屬性
- QueryDict類型的對象
- 包含post請求方式的所有參數
- 與form表單中的控件對應
- 問:表單中哪些控件會被提交?
- 答:控件要有name屬性,則name屬性的值為鍵,value屬性的值為鍵,構成鍵值對提交
- 對于checkbox控件,name屬性一樣為一組,當控件被選中后會被提交,存在一鍵多值的情況
- 鍵是開發人員定下來的,值是可變的
- 示例如下
- 定義視圖postTest1
def postTest1(request):return render(request,
'booktest/postTest1.html')
url(r
'^postTest1$',views.postTest1)?
<html>
<head><title>Title</title>
</head>
<body>
<form method=
"post" action=
"/postTest2/">
姓名:<input type=
"text" name=
"uname"/><br>
密碼:<input type=
"password" name=
"upwd"/><br>
性別:<input type=
"radio" name=
"ugender" value=
"1"/>
男<input type=
"radio" name=
"ugender" value=
"0"/>女<br>
愛好:<input type=
"checkbox" name=
"uhobby" value=
"胸口碎大石"/>
胸口碎大石<input type=
"checkbox" name=
"uhobby" value=
"跳樓"/>
跳樓<input type=
"checkbox" name=
"uhobby" value=
"喝酒"/>
喝酒<input type=
"checkbox" name=
"uhobby" value=
"爬山"/>爬山<br><input type=
"submit" value=
"提交"/>
</form>
</body>
</html>
def postTest2(request):uname=request.POST[
'uname']upwd=request.POST[
'upwd']ugender=request.POST[
'ugender']uhobby=request.POST.getlist(
'uhobby')context={
'uname':uname,
'upwd':upwd,
'ugender':ugender,
'uhobby':uhobby}return render(request,
'booktest/postTest2.html',context)?
url(r
'^postTest2$',views.postTest2)
<html>
<head><title>Title</title>
</head>
<body>
{{ uname }}<br>
{{ upwd }}<br>
{{ ugender }}<br>
{{ uhobby }}
</body>
</html>?
- 注意:使用表單提交,注釋掉settings.py中的中間件crsf
HttpResponse對象
- 在django.http模塊中定義了HttpResponse對象的API
- HttpRequest對象由Django自動創建,HttpResponse對象由程序員創建
- 不調用模板,直接返回數據
#coding=utf-8
from django.http
import HttpResponsedef index(request):return HttpResponse(
'你好')
from django.http
import HttpResponse
from django.template
import RequestContext, loaderdef index(request):t1 = loader.get_template(
'polls/index.html')context = RequestContext(request, {
'h1':
'hello'})return HttpResponse(t1.render(context))?
屬性
- content:表示返回的內容,字符串類型
- charset:表示response采用的編碼字符集,字符串類型
- status_code:響應的HTTP響應狀態碼
- content-type:指定輸出的MIME類型
方法
- init?:使用頁內容實例化HttpResponse對象
- write(content):以文件的方式寫
- flush():以文件的方式輸出緩存區
- set_cookie(key, value='', max_age=None, expires=None):設置Cookie
- key、value都是字符串類型
- max_age是一個整數,表示在指定秒數后過期
- expires是一個datetime或timedelta對象,會話將在這個指定的日期/時間過期,注意datetime和timedelta值只有在使用PickleSerializer時才可序列化
- max_age與expires二選一
- 如果不指定過期時間,則兩個星期后過期
from django.http
import HttpResponse
from datetime
import *
def index(request):response =
HttpResponse()if request.COOKIES.has_key(
'h1'):response.write('<h1>' + request.COOKIES[
'h1'] +
'</h1>')response.set_cookie('h1',
'你好', 120
)# response.set_cookie('h1', '你好', None, datetime(2016, 10, 31))return response
- delete_cookie(key):刪除指定的key的Cookie,如果key不存在則什么也不發生
子類HttpResponseRedirect
- 重定向,服務器端跳轉
- 構造函數的第一個參數用來指定重定向的地址
在views1.py中
from django.http
import HttpResponse,HttpResponseRedirect
def index(request):return HttpResponseRedirect(
'js/')
def index2(request,id):return HttpResponse(id) 在應用的urls.py中增加一個url對象 url(r
'^([0-9]+)/$', views1.index2, name=
'index2'),?
from django.core.urlresolvers
import reversedef index(request):return HttpResponseRedirect(reverse(
'booktest:index2', args=(1,)))
子類JsonResponse
- 返回json數據,一般用于異步請求
- _init?_(data)
- 幫助用戶創建JSON編碼的響應
- 參數data是字典對象
- JsonResponse的默認Content-Type為application/json
from django.http
import JsonResponsedef index2(requeset):return JsonResponse({
'list':
'abc'})
簡寫函數
render
- render(request, template_name[, context])
- 結合一個給定的模板和一個給定的上下文字典,并返回一個渲染后的HttpResponse對象
- request:該request用于生成response
- template_name:要使用的模板的完整名稱
- context:添加到模板上下文的一個字典,視圖將在渲染模板之前調用它
from django.shortcuts
import renderdef index(request):return render(request,
'booktest/index.html', {
'h1':
'hello'})
重定向
- redirect(to)
- 為傳遞進來的參數返回HttpResponseRedirect
- to推薦使用反向解析
from django.shortcuts
import redirect
from django.core.urlresolvers
import reversedef index(request):return redirect(reverse(
'booktest:index2'))
得到對象或返回404
- get_object_or_404(klass,?args, *kwargs)
- 通過模型管理器或查詢集調用get()方法,如果沒找到對象,不引發模型的DoesNotExist異常,而是引發Http404異常
- klass:獲取對象的模型類、Manager對象或QuerySet對象
- **kwargs:查詢的參數,格式應該可以被get()和filter()接受
- 如果找到多個對象將引發MultipleObjectsReturned異常
from django.shortcuts
import *
def detail(request, id):try:book = get_object_or_404(BookInfo, pk=
id)except BookInfo.MultipleObjectsReturned:book =
Nonereturn render(request,
'booktest/detail.html', {
'book': book}) 將settings.py中的DEBUG改為False
將請求地址輸入2和100查看效果
得到列表或返回404
- get_list_or_404(klass,?args, *kwargs)
- klass:獲取列表的一個Model、Manager或QuerySet實例
- **kwargs:查尋的參數,格式應該可以被get()和filter()接受
from django.shortcuts
import *
def index(request):# list = get_list_or_404(BookInfo, pk__lt=1)list = get_list_or_404(BookInfo, pk__lt=6
)return render(request,
'booktest/index.html', {
'list': list} 將settings.py中的DEBUG改為False
狀態保持
- http協議是無狀態的:每次請求都是一次新的請求,不會記得之前通信的狀態
- 客戶端與服務器端的一次通信,就是一次會話
- 實現狀態保持的方式:在客戶端或服務器端存儲與會話有關的數據
- 存儲方式包括cookie、session,會話一般指session對象
- 使用cookie,所有數據存儲在客戶端,注意不要存儲敏感信息
- 推薦使用sesison方式,所有數據存儲在服務器端,在客戶端cookie中存儲session_id
- 狀態保持的目的是在一段時間內跟蹤請求者的狀態,可以實現跨頁面訪問當前請求者的數據
- 注意:不同的請求者之間不會共享這個數據,與請求者一一對應
啟用session
- 使用django-admin startproject創建的項目默認啟用
- 在settings.py文件中
項INSTALLED_APPS列表中添加:
'django.contrib.sessions', 項MIDDLEWARE_CLASSES列表中添加:
'django.contrib.sessions.middleware.SessionMiddleware',
- 禁用會話:刪除上面指定的兩個值,禁用會話將節省一些性能消耗
使用session
- 啟用會話后,每個HttpRequest對象將具有一個session屬性,它是一個類字典對象
- get(key, default=None):根據鍵獲取會話的值
- clear():清除所有會話
- flush():刪除當前的會話數據并刪除會話的Cookie
- del request.session['member_id']:刪除會話
用戶登錄示例
from django.shortcuts
import render, redirect
from django.core.urlresolvers
import reversedef index(request):uname = request.session.get(
'uname')return render(request,
'booktest/index.html', {
'uname': uname})def login(request):return render(request,
'booktest/login.html')def login_handle(request):request.session['uname'] = request.POST[
'uname']return redirect(reverse(
'main:index'))def logout(request):# request.session['uname'] = None# del request.session['uname']# request.session.clear()
request.session.flush()return redirect(reverse(
'main:index'))?
主url:
from django.conf.urls
import include, url
urlpatterns =
[url(r'^', include(
'booktest.urls', namespace=
'main'))
]應用url:
from django.conf.urls
import url
from .
import views
urlpatterns =
[url(r'^$', views.index, name=
'index'),url(r'login/$', views.login, name=
'login'),url(r'login_handle/$', views.login_handle, name=
'login_handle'),url(r'logout/$', views.logout, name=
'logout')
]?
<!DOCTYPE html>
<html>
<head><title>首頁</title>
</head>
<body>
你好:{{uname}}
<hr/>
<a href=
"{%url 'main:login'%}">登錄</a>
<hr/>
<a href=
"{%url 'main:logout'%}">退出</a>
</body>
</html>
<!DOCTYPE html>
<html>
<head><title>登錄</title>
</head>
<body>
<form method=
"post" action=
"/login_handle/"><input type=
"text" name=
"uname"/><input type=
"submit" value=
"登錄"/>
</form>
</body>
</html>
會話過期時間
- set_expiry(value):設置會話的超時時間
- 如果沒有指定,則兩個星期后過期
- 如果value是一個整數,會話將在values秒沒有活動后過期
- 若果value是一個imedelta對象,會話將在當前時間加上這個指定的日期/時間過期
- 如果value為0,那么用戶會話的Cookie將在用戶的瀏覽器關閉時過期
- 如果value為None,那么會話永不過期
- 修改視圖中login_handle函數,查看效果
def login_handle(request):request.session['uname'] = request.POST[
'uname']# request.session.set_expiry(10)# request.session.set_expiry(timedelta(days=5))# request.session.set_expiry(0)# request.session.set_expiry(None)return redirect(reverse(
'main:index'))
存儲session
- 使用存儲會話的方式,可以使用settings.py的SESSION_ENGINE項指定
- 基于數據庫的會話:這是django默認的會話存儲方式,需要添加django.contrib.sessions到的INSTALLED_APPS設置中,運行manage.py migrate在數據庫中安裝會話表,可顯示指定為
SESSION_ENGINE=
'django.contrib.sessions.backends.db' - 基于緩存的會話:只存在本地內在中,如果丟失則不能找回,比數據庫的方式讀寫更快
SESSION_ENGINE=
'django.contrib.sessions.backends.cache' - 可以將緩存和數據庫同時使用:優先從本地緩存中獲取,如果沒有則從數據庫中獲取
SESSION_ENGINE=
'django.contrib.sessions.backends.cached_db'?
使用Redis緩存session
- 會話還支持文件、純cookie、Memcached、Redis等方式存儲,下面演示使用redis存儲
- 安裝包
pip install django-redis-sessions?
SESSION_ENGINE =
'redis_sessions.session'
SESSION_REDIS_HOST =
'localhost'
SESSION_REDIS_PORT = 6379
SESSION_REDIS_DB =
0
SESSION_REDIS_PASSWORD =
''
SESSION_REDIS_PREFIX =
'session'?
啟動:sudo redis-server /etc/redis/
redis.conf
停止:sudo redis-
server stop
重啟:sudo redis-
server restart
redis-
cli:使用客戶端連接服務器
keys *
:查看所有的鍵
get name:獲取指定鍵的值
del name:刪除指定名稱的鍵?
總結
- 定義視圖
- 配置url
- request對象
- response對象
- 狀態保持
作業
轉載于:https://www.cnblogs.com/alexzhang92/p/9502397.html
總結
以上是生活随笔為你收集整理的django之视图的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。