Django 視圖層

視圖

一個視圖函數,簡稱視圖,是一個簡單的Python 函數,它接受Web請求而且返回Web響應。響應能夠是一張網頁的HTML內容,一個重定向,一個404錯誤,一個XML文檔,或者一張圖片. . . 是任何東西均可以。不管視圖自己包含什麼邏輯,都要返回響應。代碼寫在哪裏也無所謂,只要它在你的Python目錄下面。除此以外沒有更多的要求了。爲了將代碼放在某處,約定是將視圖放置在項目或應用程序目錄中的名爲views.py的文件中。html

1、HttpRequest對象

django將請求報文中的請求行、首部信息、內容主體封裝成 HttpRequest 類中的屬性。python

"""
1、屬性
1. HttpRequest.scheme
字符串類型,表示請求的協議種類,'http'或'https'。
 
2. HttpRequest.body
一個字符串,表明請求報文的主體。在處理非 HTTP 形式的報文時很是有用,例如:二進制圖像、XML等。若是要處理常規的表單數據,應該使用HttpRequest.POST。
還可使用相似讀寫文件的方式從HttpRequest中讀取數據,參見HttpRequest.read()。
 
3. HttpRequest.path
字符串類型,表示當前請求頁面的完整路徑,可是不包括協議名和域名。例如:"/music/bands/the_beatles/"。這個屬性,常被用於咱們進行某項操做時,若是不經過,返回用戶先前瀏覽的頁面。很是有用!
 
4. HttpRequest.path_info
在某些Web服務器配置下,主機名後的URL部分被分紅腳本前綴部分和路徑信息部分。path_info 屬性將始終包含路徑信息部分,不論使用的Web服務器是什麼。使用它代替path可讓代碼在測試和開發環境中更容易地切換。
 
例如,若是應用的WSGIScriptAlias設置爲/minfo,那麼HttpRequest.path等於/music/bands/the_beatles/ ,而HttpRequest.path_info爲/minfo/music/bands/the_beatles/。
 
5. HttpRequest.method
字符串類型,表示請求使用的HTTP方法。默認爲大寫。 像這樣:
 
if request.method == 'GET':
    do_something()
elif request.method == 'POST':
    do_something_else()
經過這個屬性來判斷請求的方法,而後根據請求的方法不一樣,在視圖中執行不一樣的代碼。
 
6. HttpRequest.encoding
一個字符串,表示提交的數據的編碼方式(若是爲 None 則表示使用 DEFAULT_CHARSET 的設置,默認爲 'utf-8')。
這個屬性是可寫的,你能夠修改它來修改訪問表單數據使用的編碼。
接下來對屬性的任何訪問(例如從 GET 或 POST 中讀取數據)將使用新的 encoding 值。
若是你知道表單數據的編碼不是 DEFAULT_CHARSET ,則使用它。
 
7. HttpRequest.content_type
Django1.10中新增。表示從CONTENT_TYPE頭解析的請求的MIME類型。
 
8. HttpRequest.content_params
Django 1.10中新增。包含在CONTENT_TYPE標題中的鍵/值參數字典。
 
9 HttpRequest.GET
一個相似於字典的對象,包含GET請求中的全部參數。 詳情參考QueryDict文檔。
 
注意:鍵值對的值是多個的時候,好比checkbox類型的input標籤,select標籤,須要用:
request.POST.getlist("hobby")
 
10. HttpRequest.POST
一個包含全部POST請求的參數,以及包含表單數據的字典。 詳情請參考QueryDict文檔。 若是須要訪問請求中的原始或非表單數據,可使用HttpRequest.body屬性。
 
注意:請使用if request.method == "POST"來判斷一個請求是否POST類型,而不要使用if request.POST。
POST中不包含上傳文件的數據。文件信息將包含在 FILES 屬性中。
 
11. HttpRequest.COOKIES
包含全部Cookie信息的字典。 鍵和值都爲字符串。能夠相似字典類型的方式,在cookie中讀寫數據,可是注意cookie是不安全的,所以,不要寫敏感重要的信息。
 
12. HttpRequest.FILES
一個相似於字典的對象,包含全部的上傳文件信息。
FILES 中的每一個鍵爲<input type="file" name="" /> 中的name,值則爲對應的數據。
注意,FILES 只有在請求的方法爲POST 且提交的<form> 帶有enctype="multipart/form-data" 的狀況下才會
包含數據。不然,FILES 將爲一個空的相似於字典的對象。
 
13. HttpRequest.META
包含全部HTTP頭部信息的字典。 可用的頭部信息取決於客戶端和服務器,下面是一些示例:
 
CONTENT_LENGTH —— 請求正文的長度(以字符串計)。
CONTENT_TYPE —— 請求正文的MIME類型。
HTTP_ACCEPT —— 可接收的響應Content-Type。
HTTP_ACCEPT_ENCODING —— 可接收的響應編碼類型。
HTTP_ACCEPT_LANGUAGE —— 可接收的響應語言種類。
HTTP_HOST —— 客服端發送的Host頭部。
HTTP_REFERER —— Referring頁面。
HTTP_USER_AGENT —— 客戶端的user-agent字符串。
QUERY_STRING —— 查詢字符串。
REMOTE_ADDR —— 客戶端的IP地址。想要獲取客戶端的ip信息,就在這裏!
REMOTE_HOST —— 客戶端的主機名。
REMOTE_USER —— 服務器認證後的用戶,若是可用。
REQUEST_METHOD —— 表示請求方法的字符串,例如"GET" 或"POST"。
SERVER_NAME —— 服務器的主機名。
SERVER_PORT —— 服務器的端口(字符串)。
以上只是比較重要和經常使用的,還有不少未列出。
 
從上面能夠看到,除CONTENT_LENGTH和CONTENT_TYPE以外,請求中的任何HTTP頭部鍵轉換爲META鍵時,都會將全部字母大寫並將鏈接符替換爲下劃線最後加上HTTP_前綴。因此,一個叫作X-Bender的頭部將轉換成META中的HTTP_X_BENDER鍵。
 
13. HttpRequest.resolver_match
表明一個已解析的URL的ResolverMatch實例。
 
 
 
2、可自定義的屬性
Django不會自動設置下面這些屬性,而是由你本身在應用程序中設置並使用它們。
 
1. HttpRequest.current_app
表示當前app的名字。url模板標籤將使用其值做爲reverse()方法的current_app參數。
 
2. HttpRequest.urlconf
設置當前請求的根URLconf,用於指定不一樣的url路由進入口,這將覆蓋settings中的ROOT_URLCONF設置。
將它的值修改成None,能夠恢復使用ROOT_URLCONF設置。
 
 
 
 
3、由中間件設置的屬性
Django的contrib應用中包含的一些中間件會在請求上設置屬性。
 
1. HttpRequest.session
一個既可讀又可寫的相似於字典的對象,表示當前的會話。只有當Django 啓用會話的支持時纔可用。
SessionMiddleware中間件:一個可讀寫的,相似字典的對象,表示當前會話。咱們要保存用戶狀態,回話過程等等,靠的就是這個中間件和這個屬性。
 
2. HttpRequest.site
CurrentSiteMiddleware中間件:get_current_site()方法返回的Site或RequestSite的實例,表明當前站點是哪一個。
 
Django是支持多站點的,若是你同時上線了幾個站點,就須要爲每一個站點設置一個站點id。
 
3. HttpRequest.user(用戶認證組件下使用)
AuthenticationMiddleware中間件:表示當前登陸的用戶的AUTH_USER_MODEL的實例,這個模型是Django內置的Auth模塊下的User模型。若是用戶當前未登陸,則user將被設置爲AnonymousUser的實例。
可使用is_authenticated方法判斷當前用戶是否合法用戶,以下所示:
 
 
  一個 AUTH_USER_MODEL 類型的對象,表示當前登陸的用戶。
 
  若是用戶當前沒有登陸,user 將設置爲 django.contrib.auth.models.AnonymousUser 的一個實例。你能夠經過 is_authenticated() 區分它們。
 
    例如:
 
    if request.user.is_authenticated():
        # Do something for logged-in users.
    else:
        # Do something for anonymous users.
 
 
       user 只有當Django 啓用 AuthenticationMiddleware 中間件時纔可用。
 
     -------------------------------------------------------------------------------------
 
    匿名用戶
    class models.AnonymousUser
 
    django.contrib.auth.models.AnonymousUser 類實現了django.contrib.auth.models.User 接口,但具備下面幾個不一樣點:
 
    id 永遠爲None。
    username 永遠爲空字符串。
    get_username() 永遠返回空字符串。
    is_staff 和 is_superuser 永遠爲False。
    is_active 永遠爲 False。
    groups 和 user_permissions 永遠爲空。
    is_anonymous() 返回True 而不是False。
    is_authenticated() 返回False 而不是True。
    set_password()、check_password()、save() 和delete() 引起 NotImplementedError。
    New in Django 1.8:
    新增 AnonymousUser.get_username() 以更好地模擬 django.contrib.auth.models.User。
 
"""
request屬性
"""
1.HttpRequest.get_full_path()
 
  返回 path,若是能夠將加上查詢字符串。
 
  例如:"/music/bands/the_beatles/?print=true"
 
 
2.HttpRequest.is_ajax()
 
  若是請求是經過XMLHttpRequest 發起的,則返回True,方法是檢查 HTTP_X_REQUESTED_WITH 相應的首部是不是字符串'XMLHttpRequest'。
 
  大部分現代的 JavaScript 庫都會發送這個頭部。若是你編寫本身的 XMLHttpRequest 調用(在瀏覽器端),你必須手工設置這個值來讓 is_ajax() 能夠工做。
 
  若是一個響應須要根據請求是不是經過AJAX 發起的,而且你正在使用某種形式的緩存例如Django 的 cache middleware,
   你應該使用 vary_on_headers('HTTP_X_REQUESTED_WITH') 裝飾你的視圖以讓響應可以正確地緩存。
"""
 
"""
1. HttpRequest.get_host()[source]
根據HTTP_X_FORWARDED_HOST和HTTP_HOST頭部信息獲取請求的原始主機。 若是這兩個頭部沒有提供相應的值,則使用SERVER_NAME和SERVER_PORT。
 
例如:"127.0.0.1:8000"
 
注:當主機位於多個代理的後面,get_host()方法將會失敗。解決辦法之一是使用中間件重寫代理的頭部,以下面的例子:
 
from django.utils.deprecation import MiddlewareMixin
 
class MultipleProxyMiddleware(MiddlewareMixin):
    FORWARDED_FOR_FIELDS = [
        'HTTP_X_FORWARDED_FOR',
        'HTTP_X_FORWARDED_HOST',
        'HTTP_X_FORWARDED_SERVER',
    ]
 
    def process_request(self, request):
 
        Rewrites the proxy headers so that only the most
        recent proxy is used.
 
        for field in self.FORWARDED_FOR_FIELDS:
            if field in request.META:
                if ',' in request.META[field]:
                    parts = request.META[field].split(',')
                    request.META[field] = parts[-1].strip()
                     
2. HttpRequest.get_port()[source]
使用META中HTTP_X_FORWARDED_PORT和SERVER_PORT的信息返回請求的始發端口。
 
3. HttpRequest.get_full_path()[source]
返回包含完整參數列表的path。例如:/music/bands/the_beatles/?print=true
 
4. HttpRequest.build_absolute_uri(location)[source]

返回location的絕對URI形式。 若是location沒有提供,則使用request.get_full_path()的值。
 
例如:"https://example.com/music/bands/the_beatles/?print=true"
 
注:不鼓勵在同一站點混合部署HTTP和HTTPS,若是須要將用戶重定向到HTTPS,最好使用Web服務器將全部HTTP流量重定向到HTTPS。
 
5. HttpRequest.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)[source]
從已簽名的Cookie中獲取值,若是簽名不合法則返回django.core.signing.BadSignature。
可選參數salt用來爲密碼加鹽,提升安全係數。 max_age參數用於檢查Cookie對應的時間戳是否超時。
 
6. HttpRequest.is_secure()[source]
若是使用的是Https,則返回True,表示鏈接是安全的。
 
7. HttpRequest.is_ajax()[source]
若是請求是經過XMLHttpRequest生成的,則返回True。
這個方法的做用就是判斷,當前請求是否經過ajax機制發送過來的。
 
8. HttpRequest.read(size=None)[source]
9. HttpRequest.readline()[source]
10. HttpRequest.readlines()[source]
11. HttpRequest.xreadlines()[source]
12. HttpRequest.iter()
上面的幾個方法都是從HttpRequest實例讀取文件數據的方法。
 
能夠將HttpRequest實例直接傳遞到XML解析器,例如ElementTree:
 
import xml.etree.ElementTree as ET
for element in ET.iterparse(request):
    process(element)
 
"""
request經常使用方法

2、HttpResponse對象

響應對象主要有三種形式:web

  • HttpResponse():HttpResponse()括號內直接跟一個具體的字符串做爲響應體,比較直接很簡單,因此這裏主要介紹後面兩種形式。
  • render():render方法就是將一個模板頁面中的模板語法進行渲染,最終渲染成一個html頁面做爲響應體。
  • redirect():重定向一個URL
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
"""
render(request, template_name[, context])
結合一個給定的模板和一個給定的上下文字典,並返回一個渲染後的 HttpResponse 對象。
參數:
  request: 用於生成響應的請求對象。
  template_name:要使用的模板的完整名稱,可選的參數
  context:添加到模板上下文的一個字典。默認是一個空字典。若是字典中的某個值是可調用的,視圖將在渲染模板以前調用它。
  render方法就是將一個模板頁面中的模板語法進行渲染,最終渲染成一個html頁面做爲響應體。
"""
return render(request, "index.html" ,{ "timer" :ctime}) #  index.html 模板文件
# return render(request, "index.html", locals())  #
 
# HttpResponse
return HttpResponse(reverse( "app01:index" ))
return HttpResponse( "<h1>OK</h1>" )
 
#redirect
return redirect( "/index/" )
return redirect( 'http://baidu.com/' )
"""
1、使用方法
1. 傳遞一個字符串
return HttpResponse("<h1>OK</h1>")

2. 傳遞可迭代對象
HttpResponse會當即處理這個迭代器,並把它的內容存成字符串,最後廢棄這個迭代器。好比文件在讀取後,會馬上調用close()方法,關閉文件。

3. 設置頭部字段
能夠把HttpResponse對象看成一個字典同樣,在其中增長和刪除頭部字段。
>>> response = HttpResponse()
>>> response['Age'] = 120
>>> del response['Age']
注意!與字典不一樣的是,若是要刪除的頭部字段若是不存在,del不會拋出KeyError異常。
HTTP的頭部字段中不能包含換行。因此若是咱們提供的頭部字段值包含換行符(CR或者LF),將會拋出BadHeaderError異常。

4. 告訴瀏覽器將響應視爲文件附件
讓瀏覽器以文件附件的形式處理響應, 須要聲明content_type類型和設置Content-Disposition頭信息。 例如,給瀏覽器返回一個微軟電子表格:
>>> response = HttpResponse(my_data, content_type='application/vnd.ms-excel')
>>> response['Content-Disposition'] = 'attachment; filename="foo.xls"'

2、屬性
1. HttpResponse.content
響應的內容。bytes類型。

2. HttpResponse.charset
編碼的字符集。 若是沒指定,將會從content_type中解析出來。

3. HttpResponse.status_code
響應的狀態碼,好比200。

4. HttpResponse.reason_phrase
響應的HTTP緣由短語。 使用標準緣由短語。

除非明確設置,不然reason_phrase由status_code的值決定。

5. HttpResponse.streaming
這個屬性的值老是False。因爲這個屬性的存在,使得中間件可以區別對待流式響應和常規響應。

6. HttpResponse.closed
若是響應已關閉,那麼這個屬性的值爲True。

3、 方法
1. HttpResponse.init(content='', content_type=None, status=200, reason=None, charset=None)[source]
響應的實例化方法。使用content參數和content-type實例化一個HttpResponse對象。

content應該是一個迭代器或者字符串。若是是迭代器,這個迭代期返回的應是一串字符串,而且這些字符串鏈接起來造成response的內容。 若是不是迭代器或者字符串,那麼在其被接收的時候將轉換成字符串。

content_type是可選地,用於填充HTTP的Content-Type頭部。若是未指定,默認狀況下由DEFAULT_CONTENT_TYPE和DEFAULT_CHARSET設置組成:text/html; charset=utf-8。

status是響應的狀態碼。reason是HTTP響應短語。charset是編碼方式。

2. HttpResponse.has_header(header)
檢查頭部中是否有給定的名稱(不區分大小寫),返回True或 False。

3. HttpResponse.setdefault(header, value)
設置一個頭部,除非該頭部已經設置過了。

4. HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=False)
設置一個Cookie。 參數與Python標準庫中的Morsel.Cookie對象相同。

max_age: 生存週期,以秒爲單位。

expires:到期時間。

domain: 用於設置跨域的Cookie。例如domain=".lawrence.com"將設置一個www.lawrence.com、blogs.lawrence.com和calendars.lawrence.com均可讀的Cookie。 不然,Cookie將只能被設置它的域讀取。

若是你想阻止客服端的JavaScript訪問Cookie,能夠設置httponly=True。

5. HttpResponse.set_signed_cookie(key, value, salt='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=True)
與set_cookie()相似,可是在設置以前將對cookie進行加密簽名。一般與HttpRequest.get_signed_cookie()一塊兒使用。

6. HttpResponse.delete_cookie(key, path='/', domain=None)
刪除Cookie中指定的key。

因爲Cookie的工做方式,path和domain應該與set_cookie()中使用的值相同,不然Cookie不會刪掉。

7. HttpResponse.write(content)[source]
將HttpResponse實例看做相似文件的對象,往裏面添加內容。

8. HttpResponse.flush()
清空HttpResponse實例的內容。

9. HttpResponse.tell()[source]
將HttpResponse實例看做相似文件的對象,移動位置指針。

10. HttpResponse.getvalue()[source]
返回HttpResponse.content的值。 此方法將HttpResponse實例看做是一個相似流的對象。

11. HttpResponse.readable()
Django1.10中的新功能,值始終爲False。

12. HttpResponse.seekable()
Django1.10中的新功能,值始終爲False。

13. HttpResponse.writable()[source]
Django1.10中的新功能,值始終爲True。

14. HttpResponse.writelines(lines)[source]
將一個包含行的列表寫入響應對象中。 不添加分行符。

4、HttpResponse的子類
Django包含了一系列的HttpResponse衍生類(子類),用來處理不一樣類型的HTTP響應。與HttpResponse相同, 這些衍生類存在於django.http之中。

class HttpResponseRedirect[source]:重定向,返回302狀態碼。已經被redirect()替代。
class HttpResponsePermanentRedirect[source]:永久重定向,返回301狀態碼。
class HttpResponseNotModified[source]:未修改頁面,返回304狀態碼。
class HttpResponseBadRequest[source]:錯誤的請求,返回400狀態碼。
class HttpResponseNotFound[source]:頁面不存在,返回404狀態碼。
class HttpResponseForbidden[source]:禁止訪問,返回403狀態碼。
class HttpResponseNotAllowed[source]:禁止訪問,返回405狀態碼。
class HttpResponseGone[source]:過時,返回405狀態碼。
class HttpResponseServerError[source]:服務器錯誤,返回500狀態碼。


5、JsonResponse類
class JsonResponse(data,encoder = DjangoJSONEncoder,safe = True,json_dumps_params = None ,** kwargs)[source]

JsonResponse是HttpResponse的一個子類,是Django提供的用於建立JSON編碼類型響應的快捷類。

它從父類繼承大部分行爲,並具備如下不一樣點:

它的默認Content-Type頭部設置爲application/json。

它的第一個參數data,一般應該爲一個字典數據類型。 若是safe參數設置爲False,則能夠是任何可JSON 序列化的對象。

encoder默認爲django.core.serializers.json.DjangoJSONEncoder,用於序列化數據。
布爾類型參數safe默認爲True。 若是設置爲False,能夠傳遞任何對象進行序列化(不然,只容許dict 實例)。
典型的用法以下:

>>> from django.http import JsonResponse
>>> response = JsonResponse({'foo': 'bar'})
>>> response.content
b'{"foo": "bar"}'
若要序列化非dict對象,必須設置safe參數爲False:

>>> response = JsonResponse([1, 2, 3], safe=False)
若是不傳遞safe=False,將拋出一個TypeError。
若是你須要使用不一樣的JSON 編碼器類,能夠傳遞encoder參數給構造函數:
>>> response = JsonResponse(data, encoder=MyJSONEncoder)

6、StreamingHttpResponse類
StreamingHttpResponse類被用來從Django響應一個流式對象到瀏覽器。若是生成的響應太長或者是佔用的內存較大,這麼作可能更有效率。 例如,它對於生成大型的CSV文件很是有用。

StreamingHttpResponse不是HttpResponse的衍生類(子類),由於它實現了徹底不一樣的應用程序接口。可是,除了幾個明顯不一樣的地方,二者幾乎徹底相同。

7、FileResponse
文件類型響應。一般用於給瀏覽器返回一個文件附件。

FileResponse是StreamingHttpResponse的衍生類,爲二進制文件專門作了優化。

FileResponse須要經過二進制模式打開文件,以下:

>>> from django.http import FileResponse
>>> response = FileResponse(open('myfile.png', 'rb'))

"""
HttpResponse對象

3、自定義錯誤頁面

當Django找不到與請求匹配的URL時,或者當拋出一個異常時,將調用一個錯誤處理視圖。錯誤視圖包括400、40三、404和500,分別表示請求錯誤、拒絕服務、頁面不存在和服務器錯誤。它們分別位於ajax

  • handler400 —— django.conf.urls.handler400。
  • handler403 —— django.conf.urls.handler403。
  • handler404 —— django.conf.urls.handler404。
  • handler500 —— django.conf.urls.handler500。

這些值能夠在根URLconf中設置。在其它app中的二級URLconf中設置這些變量無效。django

Django有內置的HTML模版,用於返回錯誤頁面給用戶,可是這些403,404頁面實在醜陋,一般咱們都自定義錯誤頁面。json

首先,在根URLconf中額外增長下面的條目:跨域

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from django.conf.urls import url
from django.conf.urls import include
from django.contrib import admin
from . import views
 
urlpatterns = [
     url(r '^admin/' , admin.site.urls),
     url(r '^backend/' ,include( 'backend.urls' )),
     url(r '^' , include( 'web.urls' )),
]
 
# 增長的條目
handler400 = views.bad_request
handler403 = views.permission_denied
handler404 = views.page_not_found
handler500 = views.page_error

而後在,views.py文件中增長四個處理視圖:瀏覽器

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from django.shortcuts import render
def page_not_found(request):
     return render(request, '404.html' )
 
 
def page_error(request):
     return render(request, '500.html' )
 
 
def permission_denied(request):
     return render(request, '403.html' )
 
 
def bad_request(request):
     return render(request, '400.html' )
相關文章
相關標籤/搜索