12.33 Django框架簡介: MVC,全名是Model View Controller,是軟體工程中的一種軟體架構模式,把軟體系統分為三個基本部分:模型(Model)、視圖(View)和控制器(Controller),具有耦合性低、重用性高、生命周期成本低等優點 Django框架的設計模式借鑒 ...
12.33 Django框架簡介:
MVC,全名是Model View Controller,是軟體工程中的一種軟體架構模式,把軟體系統分為三個基本部分:模型(Model)、視圖(View)和控制器(Controller),具有耦合性低、重用性高、生命周期成本低等優點
Django框架的設計模式借鑒了MVC框架的思想,也是分成三部分,來降低各個部分之間的耦合性。
Django框架的不同之處在於它拆分的三部分為:Model(模型)、Template(模板)和View(視圖),也就是MTV框架。
Model(模型):負責業務對象與資料庫的對象(ORM)
Template(模版):負責如何把頁面展示給用戶
View(視圖):負責業務邏輯,併在適當的時候調用Model和Template
此外,Django還有一個urls分發器,它的作用是將一個個URL的頁面請求分發給不同的view處理,view再調用相應的Model和Template
12.34 View(視圖)
一個視圖函數(類),簡稱視圖,是一個簡單的Python 函數(類),它接受Web請求並且返回Web響應。
響應可以是一張網頁的HTML內容,一個重定向,一個404錯誤,一個XML文檔,或者一張圖片。
12.341 CBV(class base view)
urls.py:
url(r'^add_class/$', views.AddClass.as_view()),
CBV版添加班級:
from django.shortcuts import HttpResponse, render, redirect from django.views import View from app01 import models 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/")
12.342 視圖裝飾器
裝飾器裝飾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:
類中的方法與獨立函數不完全相同,因此不能直接將函數裝飾器應用於類中的方法 ,需要先將其轉換為方法裝飾器。
Django中提供了method_decorator裝飾器用於將函數裝飾器轉換為方法裝飾器
# CBV版添加班級 from django.views import View from django.utils.decorators import method_decorator 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 #@method_decorator(wrapper, name='post') 給post加方法裝飾器 #@method_decorator(wrapper, name='dispatch') 給dispatch方法加裝飾器,相當於給類下所有方法加裝飾器 class AddClass(View): #http_method_names = ['get', ] #自定義可用的請求方法 @method_decorator(wrapper) #給get方法加裝飾器 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/")
使用CBV時要註意:請求過來後會先執行dispatch()這個方法,如果需要批量對具體的請求處理方法,如get,post等做一些操作的時候,這裡我們可以手動改寫dispatch方法,這個dispatch方法就和在FBV上加裝飾器的效果一樣。
class Login(View): def dispatch(self, request, *args, **kwargs): print('before') obj = super(Login,self).dispatch(request, *args, **kwargs) print('after') return obj def get(self,request): return render(request,'login.html') def post(self,request): print(request.POST.get('user')) return HttpResponse('Login.post')
12.342 request對象
當一個頁面被請求時,Django就會創建一個包含本次請求原信息的HttpRequest對象,Django會將這個對象自動傳遞給響應的視圖函數,一般視圖函數約定俗成地使用 request 參數承接這個對象
path_info | 返回用戶訪問url的路徑,不包括功能變數名稱和參數:/music/bands/the_beatles/ | |
---|---|---|
method | 請求中使用的HTTP方法的字元串表示,全大寫表示:"GET"、"POST" | |
GET | 包含所有HTTP GET參數的類字典對象 | |
POST | 包含所有HTTP POST參數的類字典對象 | |
body | 請求體,byte類型 request.POST的數據就是從body裡面提取到的 | |
get_full_path() | 返回URL中的路徑和參數:/music/bands/the_beatles/?print=true |
12.343 上傳文件示例
如果有上傳文件,html文件中的form表單一定要加 enctype="multipart/form-data"
upload_demo.html:
<body> <h1>Django 上傳文件示例</h1> <form action="/upload/" method="post" enctype="multipart/form-data"> <input type="text" name="username"> <input type="file" name="touxiang"> <input type="submit" value="提交"> </form> </body>
如果有上傳文件,views.py中應該從request.FILES中取上傳的文件對象
服務端接收文件:views.py
from django.shortcuts import render, HttpResponse from django.http import JsonResponse def upload(request): if request.method == "POST": #print(request.POST) #只能拿到字典里的文件名 #print(request.FILES) #拿到含有文件對象的字典 file_obj = request.FILES.get("touxiang") #得到文件對象 #print(file_obj, type(file_obj)) file_name = file_obj.name # 拿到文件名 with open(file_name, "wb") as f: for line in file_obj.chunks(): # 從上傳的文件對象中一點一點讀取數據 f.write(line) # 寫到新建的文件中 return HttpResponse("OK") return render(request, "upload_demo.html")
12.344 Response對象
每個視圖都需要實例化,填充和返回一個HttpResponse,本質上render,redirect也是返回了HttpResponse對象
HttpResponse.content:響應內容 HttpResponse.charset:響應內容的編碼 HttpResponse.status_code:響應的狀態碼
JsonResponse對象:JsonResponse是HttpResponse的子類,Django封裝的一個專門用來返回JSON格式數據的方法
from django.http.response import JsonResponse def get_json_data(request): data = {"name": "Egon", "hobby": "喊麥"} # import json # return HttpResponse(json.dumps(data),content_type='application/json') #設置content_type,瀏覽器會自動反序列化json <-等同於-> # ret = HttpResponse(json.dumps(data)) # ret['Content-type'] = 'application/json' # return ret return JsonResponse(data) #return JsonResponse([1, 2, 3, 4], safe=False) #JsonResponse預設只能傳遞字典類型,如果要傳遞非字典類型需要設置safe參數