Django 視圖系統

Django 視圖系統

概念

  • 一個視圖函數,簡稱視圖,是一個簡單的Python函數,用於接受Web請求並返回Web響應。
  • 一般將視圖函數寫在project或app目錄中的名爲views.py文件中

簡單的實例

 

from django.http import HttpResponse
import datetime


def current_datetime(request):   now = datetime.datetime.now()   html = "<html><body>It is now %s.</body></html>" % now return HttpResponse(html)

 

 

 

定義方式

CBV

  可讀性更增強,將post 和 get請求分開用兩個方法定義html

  記得更改urls中的調用方式python

實例ajax

# CBV版添加班級
from django.views import View
class AddClass(View):
  
  def get(self, request):
  return render(request, "add_class.html")
  
  def post(self, request):
    class_name = request.POST.get("class_name")
    models.Classes.objects.create(name=class_name)
  return redirect("/class_list/")

# urls.py中
url(r'^add_class/$', views.AddClass.as_view()),

FBV

  代碼更加簡潔,可是可讀性差,urls 中的調用方式簡單django

實例瀏覽器

def add_class(request):
  if request.method == "POST":
    class_name = request.POST.get("class_name")
    models.Classes.objects.create(name=class_name)
    return redirect("/class_list/")
  return render(request, "add_class.html")

CBV 源碼剖析 以及 重寫方法

CBV 源碼順序

  經過調用 View 中的 as_view() 調用  view 再調用 dispatch 緩存

  本質上執行的則是 dispatch 安全

重寫 dispatch()   

利用 super 執行父類中的 dispatch 方法後再執行本身的服務器

重寫dispatch函數能夠實現cookie

  全部類型的函數執行的時候都作一個固定操做的插入session

from django.shortcuts import render,HttpResponse
from django.views import View

class LoginView(View):
  defdispatch(self, request, *args, **kwargs): ... ret = super().dispatch(self, request, *args, **kwargs) return ret def get(self): ... return HttpResponse("ok")

給視圖加裝飾器 

使用裝飾器裝飾FBV

  FBV自己就是一個函數,因此和給普通的函數加裝飾器無差異

示例

def wrapper(func):
  def inner(*args, **kwargs):
    start_time = time.time()
    ret = func(*args, **kwargs)
    end_time = time.time()
    print("used:", end_time-start_time)
  return ret
return inner

# FBV版添加班級
@wrapper def add_class(request):
  if request.method == "POST":
    class_name = request.POST.get("class_name")
    models.Classes.objects.create(name=class_name)
  return redirect("/class_list/")
return render(request, "add_class.html")

 

使用裝飾器裝飾CBV

類須要特殊的裝飾器進行一次封裝才行

from django.utils.decorators import method_decorator

@method_decorator(wrapper)

 

給CBV加裝飾器能夠有多種方式

  給 類 加裝飾器

from django.utils.decorators import method_decorator

@method_decorator(check_login, name="get")
@method_decorator(check_login, name="post")
class HomeView(View):

  def dispatch(self, request, *args, **kwargs):
    return super(HomeView, self).dispatch(request, *args, **kwargs)
    
  def get(self, request):
    return render(request, "home.html")
    
  def post(self, request):
    print("Home View POST method...")
    return redirect("/index/")

 

  給 post 或者 get 加裝飾器

from django.utils.decorators import method_decorator


class HomeView(View):
    
  def dispatch(self, request, *args, **kwargs)    
    return super(HomeView, self).dispatch(request, *args, **kwargs)

  def get(self, request):
    return render(request, "home.html")

  @method_decorator(check_login)
  def post(self, request):
    print("Home View POST method...")
    return redirect("/index/")

 

  給 dispatch 加裝飾器

  CBV中首先執行的就是dispatch,這樣至關於給get和post方法都加上了裝飾器

from django.utils.decorators import method_decorator


class HomeView(View):    
    
  @method_decorator(check_login)
  def dispatch(self, request, *args, **kwargs):
    return super(HomeView, self).dispatch(request, *args, **kwargs)

  def get(self, request):
    return render(request, "home.html")

  def post(self, request):
    print("Home View POST method...")
    return redirect("/index/")

經常使用對象

request對象

  經常使用的

  • path_info      返回用戶訪問url,不包括域名
  • method    請求中使用的HTTP方法的字符串表示,全大寫表示。
  • GET         包含全部HTTP GET參數的類字典對象
  • POST      包含全部HTTP POST參數的類字典對象
  • body       請求體,byte類型 request.POST的數據就是從body裏面提取到的

  不經常使用的特麼好多

 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') 裝飾你的視圖以讓響應可以正確地緩存。
66 
67 請求相關方法
View Code

  屬性

  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     完整的細節參見會話的文檔。
140 
141 request屬性相關
View Code

  上傳文件示例

 1 Django接受上傳文件代碼
 2 
 3 from django.conf.urls import url
 4 from django.shortcuts import HttpResponse
 5 
 6 
 7 def upload(request):
 8     print("request.GET:", request.GET)
 9     print("request.POST:", request.POST)
10 
11     if request.FILES:
12         filename = request.FILES["file"].name
13         with open(filename, 'wb') as f:
14             for chunk in request.FILES['file'].chunks():
15                 f.write(chunk)
16             return HttpResponse('上傳成功')
17     return HttpResponse("收到了!")
18 
19 urlpatterns = [
20     url(r'^upload/', upload),
21 ]
View Code

HttpResponse對象    

  一般用來傳遞基本字符串信息,可指定類型 

response = HttpResponse("Here's the text of the Web page.")
response = HttpResponse("Text only, please.", content_type="text/plain")

 

  屬性

  • HttpResponse.content:響應內容
  • HttpResponse.charset:響應內容的編碼
  • HttpResponse.status_code:響應的狀態碼 

render對象

  結果返回一個網頁對象,必須帶參數request,且能夠加其餘自定義參數(參數以字典的形式,或者直接 locals

  render 渲染的究竟是什麼?

  • render渲染的是一個html文件
  • html文件中有什麼東西 render 本身是不會在乎的並且他也不認識你什麼html仍是js代碼
  • (注意是"只"!) 會將html文件中的全部的{{ }}{% %}的部分進行相應的渲染替換成所傳的值
return render(request, 'myapp/index.html', {'foo': 'bar'})

 

redirect對象

  重定向到一個另外一個URL

return redirect('/some/url/')
return redirect('http://example.com/')

 

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)
相關文章
相關標籤/搜索