規定視圖函數必須有一個返回值,前端
而且返回值的數據類型必須是 HttpResponse 對象python
返回瀏覽器一個字符串django
結合一個給定的模板和一個給定的上下文字典,並返回一個渲染後的 HttpResponse 對象。json
默認返回一個臨時的重定向;傳遞permanent=True
能夠返回一個永久的重定向。後端
擴展閱讀:瀏覽器
臨時重定向(響應狀態碼:302)和永久重定向(響應狀態碼:301)對普通用戶來講是沒什麼區別的,它主要面向的是搜索引擎的機器人。app
A頁面臨時重定向到B頁面,那搜索引擎收錄的就是A頁面。函數
A頁面永久重定向到B頁面,那搜索引擎收錄的就是B頁面。post
前提知識點:先後端數據要交互,一般狀況下采用json的字符串,後端須要寫好響應的url接口並返回json格式的字符串,前端在訪問你這個接口就好了。
先後端json 序列化和反序列化的方法
方法 | 後端 | 前端 |
---|---|---|
序列化 | json.dumps | JSON.stringfy |
反序列化 | json.loads | JSON.parse |
django很是友好,幫咱們想到了這個問題,就有現成的對象來自動轉成json的對象---JsonResponse
# 導入JsonResponse 對象 from django.http import JsonResponse def index(request): user_dict = {'username':'qinyj','age':18,'hobby':'獨角獸的好事'} # json數據序列化的時候,若是這個字典裏有中文, # 那麼序列化的時候就不能序列化中文了,須要加參數ensure_ascii=False return HttpResponse(json.dumps(user_dict,ensure_ascii=False)) # 一樣django幫你想到了這點,直接用jsonresponse對象返回就好了,不須要導入json模塊了。 # 可是一樣也是不支持中文的,須要加參數json_dumps_params={'ensure_ascii':False} return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False}) L = [1,2,3,4] # json默認是序列化字典用的,若是序列化其餘數據類型的話會報錯: # In order to allow non-dict objects to be serialized set the safe parameter to False. # 提示必需要加safe參數 return JsonResponse(L,safe=False)
基於函數版的視圖任務
def index(request): user_dict = {'username':'qinyj','age':18,'hobby':'獨角獸的好事'} # json數據序列化的時候,若是這個字典裏有中文, # 那麼序列化的時候就不能序列化中文了,須要加參數ensure_ascii=False return HttpResponse(json.dumps(user_dict,ensure_ascii=False)) # 一樣django幫你想到了這點,直接用jsonresponse對象返回就好了,不須要導入json模塊了。 # 可是一樣也是不支持中文的,須要加參數json_dumps_params={'ensure_ascii':False} return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False}) L = [1,2,3,4] # json默認是序列化字典用的,若是序列化其餘數據類型的話會報錯: # In order to allow non-dict objects to be serialized set the safe parameter to False. # 提示必需要加safe參數 return JsonResponse(L,safe=False) 而後在urls.py 路由匹配中寫匹配規則 url(r'^index/', views.index)
基於類版的視圖任務
# 導入View,繼承View類 from django.views import View class MyLogin(View): def get(self,request): print("我是MyLog裏面的get方法") return render(request,'login.html') def post(self,request): print("我是MyLog裏面的post方法") return HttpResponse("post") 而後在urls.py 路由匹配中寫匹配規則,CBV書寫方式有所不一樣 url(r'^login/', views.MyLogin.as_view()) # 經過看源碼的執行流程: # 訪問類的屬性和方法,方法加括號,執行優先級最高 # 項目一啓動 會自動執行as_views方法 # 第一步 會 變形爲 views.view # url(r'login/',views.view), # 而後進入view函數 --> self.dispatch(request, *args, **kwargs) --> if request.method.lower() in self.http_method_names: # handler = getattr(self, request.method.lower(), self.http_method_not_allowed) --> return handler(request, *args, **kwargs)
咱們經過看CBV執行的流程源碼看出來,能夠思考一個問題,
咱們在視圖中定義兩個方法,get、post
爲何可以根據請求方式的不一樣,自動執行不一樣的方法?
django CBV方式執行源碼重要部分:
路由層經過匹配 url(r'^login/', views.MyLogin.as_view()) 首先遇到類名加括號,執行優先級最高,經過調用as_view獲得一個返回值view,把它變形, url(r'login/',views.view) 而後執行view的方法,會到dispatch方法中執行 判斷請求的方式是什麼,在不在事先定義好的方法列表裏面 而後利用反射獲得對請求方式的對象,再次return出去,執行請求方式對象裏的內容. @classonlymethod def as_view(cls, **initkwargs): """ Main entry point for a request-response process. """ ... def view(request, *args, **kwargs): self = cls(**initkwargs) if hasattr(self, 'get') and not hasattr(self, 'head'): self.head = self.get self.request = request self.args = args self.kwargs = kwargs return self.dispatch(request, *args, **kwargs) ... update_wrapper(view, cls.dispatch, assigned=()) return view def dispatch(self, request, *args, **kwargs): # 這裏判斷請求的方式是什麼,在不在事先定義好的方法列表裏面 # http_method_names = ['get', # 'post', # 'put', # 'patch', # 'delete', # 'head', # 'options', # 'trace'] if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs)
FBV加裝飾器的方式很簡單,和以前咱們加裝飾器沒有區別。
# 定義一個計算執行時間的裝飾器 def outter(func): @wraps(func) def inner(*args,**kwargs): start_time = time.time() res = func(*args,**kwargs) end_time = time.time() print('執行時間:',end_time - start_time) return res return inner # 普通函數加裝飾器 @outter def index(request): user_dict = {'username':'qinyj','age':18,'hobby':'獨角獸的好事'} # return HttpResponse(json.dumps(user_dict,ensure_ascii=False)) # json數據序列化的時候,若是這個字典裏有中文, # 那麼序列化的時候就不能序列化中文了,須要加參數ensure_ascii=False # 一樣django幫你想到了這點,直接用jsonresponse對象返回就好了,不須要導入json模塊了。 # return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False}) L = [1,2,3,4] # json默認是序列化字典用的,若是序列化其餘數據類型的話會報錯: # In order to allow non-dict objects to be serialized set the safe parameter to False. # 提示必需要加safe參數 return JsonResponse(L,safe=False)
那麼CBV加加裝飾器如何加?
@method_decorator(outter,name='get')
outter:裝飾器名稱
name=:指定哪一個方法使用裝飾器
# 定義一個計算執行時間的裝飾器 def outter(func): @wraps(func) def inner(*args,**kwargs): start_time = time.time() res = func(*args,**kwargs) end_time = time.time() print('執行時間:',end_time - start_time) return res return inner # 導入裝飾器的模塊,官方推薦寫法 from django.utils.decorators import method_decorator # 第一種方式:能夠指定給那個方法加 # @method_decorator(outter,name='get') # @method_decorator(outter,name='post') # @method_decorator(outter,name='dispatch') class MyLogin(View): # 第二種方式:在此重寫父類dispatch方法,作一些操做,給全部的方法都加上裝飾器。 @method_decorator(outter) def dispatch(self, request, *args, **kwargs): return super().dispatch(request, *args, **kwargs) # 第三中方法:能夠單獨在方法名稱上加裝飾器 # @method_decorator(outter) def get(self,request): print("我是MyLog裏面的get方法") return render(request,'login.html') def post(self,request): print("我是MyLog裏面的post方法") return HttpResponse("post") 執行結果: 我是MyLog裏面的get方法 執行時間: 0.01500082015991211 我是MyLog裏面的post方法 執行時間: 0.0