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)
可讀性更增強,將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()),
代碼更加簡潔,可是可讀性差,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")
經過調用 View 中的 as_view() 調用 view 再調用 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自己就是一個函數,因此和給普通的函數加裝飾器無差異
示例
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")
類須要特殊的裝飾器進行一次封裝才行
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/")
經常使用的
不經常使用的特麼好多
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 請求相關方法
屬性
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屬性相關
上傳文件示例
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 ]
一般用來傳遞基本字符串信息,可指定類型
response = HttpResponse("Here's the text of the Web page.") response = HttpResponse("Text only, please.", content_type="text/plain")
屬性
結果返回一個網頁對象,必須帶參數request,且能夠加其餘自定義參數(參數以字典的形式,或者直接 locals )
render 渲染的究竟是什麼?
return render(request, 'myapp/index.html', {'foo': 'bar'})
重定向到一個另外一個URL
return redirect('/some/url/') return redirect('http://example.com/')
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)