定義:一個視圖函數(或類),簡稱爲視圖,是一個簡單的python函數或類,它接受web請求而且返回web響應。html
響應能夠是一張網頁的html內容,一個重定向,一個404錯誤,一個xml文檔,或一張圖片。python
不管視圖自己包含什麼邏輯,都要返回響應,代碼寫在那裏都無所謂,只要它在你當前項目目錄下面。爲了將代碼放在某處,你們預約成俗將視圖放在項目project或應用程序app目錄中的名爲views.py的文件中。web
一、每一個視圖函數,都使用HttpRequest對象做爲第一個參數,而且一般稱之爲request。ajax
二、每一個視圖函數,都會返回一個HttpResponse對象,其中包含生成的響應。django
Django使用請求和響應對象來經過系統傳遞狀態。json
當瀏覽器向服務端請求一個頁面是,Django建立一個HttpRequest對象,該對象包含關於請求的元數據,而後,Django加載相應的視圖,將這個HttpRequest對象做爲第一個參數傳遞給視圖函數,每一個視圖函數負責返回一個HttpResponse對象。瀏覽器
常見的render,redirect,HttpResponse對象返回的都是一個HttpResponse對象。緩存
主要分爲兩類:FBV(建立視圖函數)和CBV(建立視圖類)安全
-----views.py
1 from django.shortcuts import render,Httpresponse,redirect 2 from app_name import models 3 4 def add_class(request): 5 if request.method =='POST': 6 class_name = request.POST.get('class_name') 7 models.Classes.objects.create(name=class_name) 8 return redirect('/class_list/') 9 return render(request,'add_class.html')
----urls.py
1 from app_name from views
2 urlpatterns = [
3 url(r'^addclass/$',views.add_class),]
-----views.py
1 from django.views import View 2 from app_name import models 3 4 class Add_class(View): # 必須繼承類View 5 6 def get(self,request): 7 return render(request,'add_class.html') 8 9 10 def post(self,request): 11 class_name = request.POST.get('class_name') 12 models.Classes.objects.create(name=class_name) 13 return tedirect('/class_list/')
使用CBV時,urls.py中也作對應的修改:服務器
1 # urls.py中 2 url(r'^add_class/$', views.AddClass.as_view()),
一、views.AddClass.as_view() ===》返回view函數對象
二、請求到來的時候執行view函數
2.一、實例化AddClass,賦值給self
self.reuest= request
2.二、執行self.dispatch方法(AddClass若是有,執行本身的,沒有的話執行View的)
2.2.一、判斷請求方法是否被容許
經過反射獲取到請求方法類型
容許:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
不容許:
拿到一個http_method_not_allowed方法
2.2.二、執行獲取到的方法類型對應類中定義的方法,get(request,)或post(request,)
2.2.三、獲得httpResponse對象對象,返回給self.dispatch
2.2.四、獲得HttpResponse對象,返回django處理
操做:直接在函數上方加裝飾器 @wrapper_name
必須導入:from django.utils.decorators import method_decorator
操做:三種方案
2.一、直接在方法上加:
1 @method_decorator(wapper_name) 2 def get(self,request):pass
2.二、給自定義的dispatch方法加:
1 @method_decorator(wrapper_name) 2 def dispatch(self,request,*args,**kwargs)
2.三、給類加
1 # 直接在類上面加 2 @method_decorator(wapper_name, name='post') #給方法post加裝飾器 3 @method_decorator(wapper_name, name='get') 4 class AddClass(View) 5 6 注:其實也能夠直接給View中的dispatch方法加裝飾器,這樣一樣能夠實現給本身類下的全部方法加裝飾器(本身未定義dispatch方法時) 7 @method_decorator(wapper_name, name='dispatch') 8 class AddClass(View)
注:爲視圖加裝飾器豁免單個或保護csrf_token: from django.views.decorators.csrf import csrf_exempt,csrf_protect
在FBV能夠直接上加@csrf_exempt, 但在CBV上必須在類上加且只能給dispatch方法加。
當一個頁面被請求時,Django就會船艦一個包含本次請求原信息的HttpReques對象。
Django會將這個對象自動傳遞給響應的視圖函數,通常視圖函數預約俗稱的使用request參數承接這個對象。
請求相關的經常使用值
HTTP_REFERER
屬性
全部的屬性應該被認爲是隻讀的,除非另有說明。
1 屬性: 2 django將請求報文中的請求行、頭部信息、內容主體封裝成 HttpRequest 類中的屬性。 3 除了特殊說明的以外,其餘均爲只讀的。 4 5 6 0.HttpRequest.scheme 7 表示請求方案的字符串(一般爲http或https) 8 9 1.HttpRequest.body 10 11 一個字符串,表明請求報文的主體。在處理非 HTTP 形式的報文時很是有用,例如:二進制圖片、XML,Json等。 12 13 可是,若是要處理表單數據的時候,推薦仍是使用 HttpRequest.POST 。 14 15 另外,咱們還能夠用 python 的類文件方法去操做它,詳情參考 HttpRequest.read() 。 16 17 18 19 2.HttpRequest.path 20 21 一個字符串,表示請求的路徑組件(不含域名)。 22 23 例如:"/music/bands/the_beatles/" 24 25 26 27 3.HttpRequest.method 28 29 一個字符串,表示請求使用的HTTP 方法。必須使用大寫。 30 31 例如:"GET"、"POST" 32 33 34 35 4.HttpRequest.encoding 36 37 一個字符串,表示提交的數據的編碼方式(若是爲 None 則表示使用 DEFAULT_CHARSET 的設置,默認爲 'utf-8')。 38 這個屬性是可寫的,你能夠修改它來修改訪問表單數據使用的編碼。 39 接下來對屬性的任何訪問(例如從 GET 或 POST 中讀取數據)將使用新的 encoding 值。 40 若是你知道表單數據的編碼不是 DEFAULT_CHARSET ,則使用它。 41 42 43 44 5.HttpRequest.GET 45 46 一個相似於字典的對象,包含 HTTP GET 的全部參數。詳情請參考 QueryDict 對象。 47 48 49 50 6.HttpRequest.POST 51 52 一個相似於字典的對象,若是請求中包含表單數據,則將這些數據封裝成 QueryDict 對象。 53 54 POST 請求能夠帶有空的 POST 字典 —— 若是經過 HTTP POST 方法發送一個表單,可是表單中沒有任何的數據,QueryDict 對象依然會被建立。 55 所以,不該該使用 if request.POST 來檢查使用的是不是POST 方法;應該使用 if request.method == "POST" 56 57 另外:若是使用 POST 上傳文件的話,文件信息將包含在 FILES 屬性中。 58 59 7.HttpRequest.COOKIES 60 61 一個標準的Python 字典,包含全部的cookie。鍵和值都爲字符串。 62 63 64 65 8.HttpRequest.FILES 66 67 一個相似於字典的對象,包含全部的上傳文件信息。 68 FILES 中的每一個鍵爲<input type="file" name="" /> 中的name,值則爲對應的數據。 69 70 注意,FILES 只有在請求的方法爲POST 且提交的<form> 帶有enctype="multipart/form-data" 的狀況下才會 71 包含數據。不然,FILES 將爲一個空的相似於字典的對象。 72 73 74 75 9.HttpRequest.META 76 77 一個標準的Python 字典,包含全部的HTTP 首部。具體的頭部信息取決於客戶端和服務器,下面是一些示例: 78 79 CONTENT_LENGTH —— 請求的正文的長度(是一個字符串)。 80 CONTENT_TYPE —— 請求的正文的MIME 類型。 81 HTTP_ACCEPT —— 響應可接收的Content-Type。 82 HTTP_ACCEPT_ENCODING —— 響應可接收的編碼。 83 HTTP_ACCEPT_LANGUAGE —— 響應可接收的語言。 84 HTTP_HOST —— 客服端發送的HTTP Host 頭部。 85 HTTP_REFERER —— Referring 頁面。 86 HTTP_USER_AGENT —— 客戶端的user-agent 字符串。 87 QUERY_STRING —— 單個字符串形式的查詢字符串(未解析過的形式)。 88 REMOTE_ADDR —— 客戶端的IP 地址。 89 REMOTE_HOST —— 客戶端的主機名。 90 REMOTE_USER —— 服務器認證後的用戶。 91 REQUEST_METHOD —— 一個字符串,例如"GET" 或"POST"。 92 SERVER_NAME —— 服務器的主機名。 93 SERVER_PORT —— 服務器的端口(是一個字符串)。 94 從上面能夠看到,除 CONTENT_LENGTH 和 CONTENT_TYPE 以外,請求中的任何 HTTP 首部轉換爲 META 的鍵時, 95 都會將全部字母大寫並將鏈接符替換爲下劃線最後加上 HTTP_ 前綴。 96 因此,一個叫作 X-Bender 的頭部將轉換成 META 中的 HTTP_X_BENDER 鍵。 97 98 99 10.HttpRequest.user 100 101 一個 AUTH_USER_MODEL 類型的對象,表示當前登陸的用戶。 102 103 若是用戶當前沒有登陸,user 將設置爲 django.contrib.auth.models.AnonymousUser 的一個實例。你能夠經過 is_authenticated() 區分它們。 104 105 例如: 106 107 if request.user.is_authenticated(): 108 # Do something for logged-in users. 109 else: 110 # Do something for anonymous users. 111 112 113 user 只有當Django 啓用 AuthenticationMiddleware 中間件時纔可用。 114 115 ------------------------------------------------------------------------------------- 116 117 匿名用戶 118 class models.AnonymousUser 119 120 django.contrib.auth.models.AnonymousUser 類實現了django.contrib.auth.models.User 接口,但具備下面幾個不一樣點: 121 122 id 永遠爲None。 123 username 永遠爲空字符串。 124 get_username() 永遠返回空字符串。 125 is_staff 和 is_superuser 永遠爲False。 126 is_active 永遠爲 False。 127 groups 和 user_permissions 永遠爲空。 128 is_anonymous() 返回True 而不是False。 129 is_authenticated() 返回False 而不是True。 130 set_password()、check_password()、save() 和delete() 引起 NotImplementedError。 131 New in Django 1.8: 132 新增 AnonymousUser.get_username() 以更好地模擬 django.contrib.auth.models.User。 133 134 135 136 11.HttpRequest.session 137 138 一個既可讀又可寫的相似於字典的對象,表示當前的會話。只有當Django 啓用會話的支持時纔可用。 139 完整的細節參見會話的文檔。
方法
1 1.HttpRequest.get_host() 2 3 根據從HTTP_X_FORWARDED_HOST(若是打開 USE_X_FORWARDED_HOST,默認爲False)和 HTTP_HOST 頭部信息返回請求的原始主機。 4 若是這兩個頭部沒有提供相應的值,則使用SERVER_NAME 和SERVER_PORT,在PEP 3333 中有詳細描述。 5 6 USE_X_FORWARDED_HOST:一個布爾值,用於指定是否優先使用 X-Forwarded-Host 首部,僅在代理設置了該首部的狀況下,才能夠被使用。 7 8 例如:"127.0.0.1:8000" 9 10 注意:當主機位於多個代理後面時,get_host() 方法將會失敗。除非使用中間件重寫代理的首部。 11 12 13 14 2.HttpRequest.get_full_path() 15 16 返回 path,若是能夠將加上查詢字符串。 17 18 例如:"/music/bands/the_beatles/?print=true" 19 20 21 22 3.HttpRequest.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None) 23 24 返回簽名過的Cookie 對應的值,若是簽名再也不合法則返回django.core.signing.BadSignature。 25 26 若是提供 default 參數,將不會引起異常並返回 default 的值。 27 28 可選參數salt 能夠用來對安全密鑰強力攻擊提供額外的保護。max_age 參數用於檢查Cookie 對應的時間戳以確保Cookie 的時間不會超過max_age 秒。 29 30 複製代碼 31 >>> request.get_signed_cookie('name') 32 'Tony' 33 >>> request.get_signed_cookie('name', salt='name-salt') 34 'Tony' # 假設在設置cookie的時候使用的是相同的salt 35 >>> request.get_signed_cookie('non-existing-cookie') 36 ... 37 KeyError: 'non-existing-cookie' # 沒有相應的鍵時觸發異常 38 >>> request.get_signed_cookie('non-existing-cookie', False) 39 False 40 >>> request.get_signed_cookie('cookie-that-was-tampered-with') 41 ... 42 BadSignature: ... 43 >>> request.get_signed_cookie('name', max_age=60) 44 ... 45 SignatureExpired: Signature age 1677.3839159 > 60 seconds 46 >>> request.get_signed_cookie('name', False, max_age=60) 47 False 48 複製代碼 49 50 51 52 4.HttpRequest.is_secure() 53 54 若是請求時是安全的,則返回True;即請求通是過 HTTPS 發起的。 55 56 57 58 5.HttpRequest.is_ajax() 59 60 若是請求是經過XMLHttpRequest 發起的,則返回True,方法是檢查 HTTP_X_REQUESTED_WITH 相應的首部是不是字符串'XMLHttpRequest'。 61 62 大部分現代的 JavaScript 庫都會發送這個頭部。若是你編寫本身的 XMLHttpRequest 調用(在瀏覽器端),你必須手工設置這個值來讓 is_ajax() 能夠工做。 63 64 若是一個響應須要根據請求是不是經過AJAX 發起的,而且你正在使用某種形式的緩存例如Django 的 cache middleware, 65 你應該使用 vary_on_headers('HTTP_X_REQUESTED_WITH') 裝飾你的視圖以讓響應可以正確地緩存。
注意:鍵值對的值是多個的時候,好比checkbox類型的input標籤,select標籤,須要用:
request.POST.getlist("hobby")
上傳文件示例
def upload(request): """ 保存上傳文件前,數據須要存放在某個位置。默認當上傳文件小於2.5M時,django會將上傳文件的所有內容讀進內存。從內存讀取一次,寫磁盤一次。 但當上傳文件很大時,django會把上傳文件寫到臨時文件中,而後存放到系統臨時文件夾中。 :param request: :return: """ if request.method == "POST": # 從請求的FILES中獲取上傳文件的文件名,file爲頁面上type=files類型input的name屬性值 filename = request.FILES["file"].name # 在項目目錄下新建一個文件 with open(filename, "wb") as f: # 從上傳的文件對象中一點一點讀 for chunk in request.FILES["file"].chunks(): # 寫入本地文件 f.write(chunk) return HttpResponse("上傳OK")
與由Django自動建立的HttpRequest對象相比,HttpResponse對象是咱們的職責範圍了。咱們寫的每一個視圖都須要實例化,填充和返回一個HttpResponse。
HttpResponse類位於django.http模塊中。
使用
傳遞字符串
from django.http import HttpResponse response = HttpResponse("Here's the text of the Web page.") response = HttpResponse("Text only, please.", content_type="text/plain")
設置或刪除響應頭信息
response = HttpResponse() response['Content-Type'] = 'text/html; charset=UTF-8' del response['Content-Type']
屬性
HttpResponse.content:響應內容
HttpResponse.charset:響應內容的編碼
HttpResponse.status_code:響應的狀態碼
JsonResponse是HttpResponse的子類,專門用來生成JSON編碼的響應。
from django.http import JsonResponse response = JsonResponse({'foo': 'bar'}) print(response.content) b'{"foo": "bar"}'
默認只能傳遞字典類型,若是要傳遞非字典類型須要設置一下safe關鍵字參數。
response = JsonResponse([1, 2, 3], safe=False)
結合一個給定的模板和一個給定的上下文字典,並返回一個渲染後的 HttpResponse 對象。
參數:
一個簡單的例子:
from django.shortcuts import render def my_view(request): # 視圖的代碼寫在這裏 return render(request, 'myapp/index.html', {'foo': 'bar'})
上面的代碼等於:
from django.http import HttpResponse from django.template import loader def my_view(request): # 視圖代碼寫在這裏 t = loader.get_template('myapp/index.html') c = {'foo': 'bar'} return HttpResponse(t.render(c, request))
參數能夠是:
默認返回一個臨時的重定向;傳遞permanent=True 能夠返回一個永久的重定向。
你能夠用多種方式使用redirect() 函數。
傳遞一個具體的ORM對象(瞭解便可)
將調用具體ORM對象的get_absolute_url() 方法來獲取重定向的URL:
from django.shortcuts import redirect def my_view(request): ... object = MyModel.objects.get(...) return redirect(object)
傳遞一個視圖的名稱
def my_view(request): ... return redirect('some-view-name', foo='bar')
傳遞要重定向到的一個具體的網址
def my_view(request): ... return redirect('/some/url/')
固然也能夠是一個完整的網址
def my_view(request): ... return redirect('http://example.com/')
默認狀況下,redirect() 返回一個臨時重定向。以上全部的形式都接收一個permanent 參數;若是設置爲True,將返回一個永久的重定向:
def my_view(request): ... object = MyModel.objects.get(...) return redirect(object, permanent=True)
擴展閱讀:
臨時重定向(響應狀態碼:302)和永久重定向(響應狀態碼:301)對普通用戶來講是沒什麼區別的,它主要面向的是搜索引擎的機器人。
A頁面臨時重定向到B頁面,那搜索引擎收錄的就是A頁面。
A頁面永久重定向到B頁面,那搜索引擎收錄的就是B頁面。
小結:
response ——》httpresponse對象
一、HttpResponse(‘字符串’) ----》頁面顯示字符串內容 【Content-Type : text/html;charset=utf8】
二、render(request,‘模板文件名’,{}) ----》返回一個完整的頁面
三、redirect(‘/index/’) 跳轉,重定向 Location:/index/
4.JsonResponse(dict) ———》 Content-Type:application/json
視圖分發:在本身的app中創建views文件夾,裏面寫視圖py文件,須要將app中的原views.py刪除!