(一)drf基礎
全稱:django-rest framework
介面:什麼是介面、restful介面規範(協議)
CBV(基於FBV的基礎上形成)、CBV生命週期原始碼----基於restful規範下的CBV介面
請求生命週期:請求元件、解析元件、響應元件
序列化元件(序列化、反序列化簡單來說就是物件轉為字串、字串轉為物件,目的是為傳輸資料(傳給別的語言或者儲存))
三大認證(重中之重):認證(使用者是否合法)、許可權(管理員、普通使用者)、頻率(次數過多限制)
其他元件(過濾、篩選、排序、分頁、路由)
1.介面
概念:聯絡兩個物質的媒介,完成資訊的互動。在web程式中,聯絡前臺頁面與後臺資料庫的媒介。
web介面組成:
url:長得像返回資料的url連結。如api.baidu.map/search
(www.baidu.com不叫介面,叫url連結,訪問只能拿到主頁。api.baidu.map/search是介面,返回的是json資料)
請求引數:前臺按照指定的key提供資料給後臺。(必須是給定的,這樣後臺才能以此提取資料再到資料庫查詢返回)
響應資料:後臺與資料庫互動後,將資料反饋給前臺。
因此,介面就是帶著請求引數訪問能夠得到響應資料的url連結。
介面 = url + 請求引數 + 響應資料
2.restful介面規範
介面規範:不同後臺語言,使用同樣的介面返回同樣的資料。
如何寫介面:要寫url和響應資料。如果將請求引數也加上,就是在寫介面文件。
兩大部分:
(1)url
1)用api關鍵字標識介面url。方式1:api.baidu.com;方式2:www.baudu.com/api
2)介面資料安全性決定優先選用https協議。
3)如果一個介面有多版本存在,需要在url中標識體現。如下的v1和v2
api.baidu.com/v1/.... api.baidu.com/v2/....
4)操作中的資料稱為資源,在url中資源一般採用複數形式,一個介面可以概括對該資源的多種操作方式。(一個url對應一個類,類裡面可以有多個請求方法)
可以對操作隱藏,並且複用性更強(寫動作了,只能適用這一個動作,不寫其他動作都可以用)如api.baidu.com/books api.baidu.com/books/(pk)
5)請求方式有多種,用一個url處理如何讓保證不混亂------通過不同的請求方式標識不同操作資源的方式
/books get 獲取所有
/books post 增加一個(多個)
/books/(pk) delete 刪除一個
/books/(pk) put 整體更新一個 #改一個使用者
/books/(pk) patch 區域性更新一個 #改一個使用者的密碼
6)資源往往涉及資料的各種操作方式:篩選、排序、限制
api.baidu.com/books/?search=寶馬&ordering=-price&limit=3
(2)響應資料
1)http請求的響應會有響應狀態碼,介面用來返回操作的資源資料,也有自己運算元據結果的資源狀態碼(status 0代表操作資源成功,1代表操作失敗,2代表操作成功,但沒匹配結果)
注:資源狀態碼和http狀態碼不一樣,為前後臺的約定
2)資源狀態碼的文字提示。
status ok “賬號有誤或者密碼有誤”
3)資源本身
results
注:刪除資源成功不做任何資料返回(只返回空字串,連狀態碼、狀態資訊都不返回)
4)不能直接返回的資源(子資源、圖片、視訊等資源),返回該資源的url連結。
https://api.baidu.com/v1/books?limit=3 get|post|delete|put|patch { “status” : 0, “msg” : “ok”, “results”: [ { “title”: “三國”, “price”: 78, “img”: “https://.....” } ] }
3.django流程
(1)專案準備:
1.分發路由 在專案資料夾的urls複製一份到應用資料夾中。然後在專案資料夾的urls分發路由給app:匯入include,然後url(r'^api/', include('api.urls'))。再在app資料夾的urls.py中分發路由給CBV 2.檢視 在應用中分發路由前,先寫類檢視 from django.http import JsonResponse from django.views import View class Book(View): def get(self, request, *args, **kwargs): return JsonResponse('get ok', safe=False) def post(self, request, *args, **kwargs): return JsonResponse('get ok', safe=False) #safe預設為true,要返回字典。不是字典否則拋異常。
3.在應用urls下分發路由 from django.conf.urls import url from . import views #注意在應用中匯入檢視都是. 從當前應用中匯入 urlpatterns = [ url(r'^books/', views.Book.as_view()), ]
4.定義模型類 (1)models.py中定義類 from django.db import models class Book(models.Model): title = models.CharField(max_length=64) price = models.DecimalField(max_digits=5, decimal_places=2) #整數、小數位 class Meta: #巢狀類(給上級類新增功能或指定標準) db_table = 'book' #自定義資料庫表名 verbose_name = "book" #給模型起個可讀的名字,預設是複數 verbose_name_plural = verbose_name #取消上面的複數 def __str__(self): #顯示的內容 return '<<%s>>' % self.title
(2)資料庫遷移 進入django的shell環境中:Tools----> run manage.py task 在shell環境中生成遷移檔案:makemigrations。然後遷移:migrate
5.生成admin (1)在amin.py中註冊並且匯入模型 from django.contrib import admin port models admin.site.register(models.Book)
(2)建立使用者 在shell環境中:createsuper建立超級使用者,然後輸入使用者密碼(郵箱不用)
|
(2)CBV的請求生命週期
請求如何到CBV下的get和post
a.請求過來,專案檔案中路由分發給應用api的路由
b.應用分發路由走as_view函式。
views.Book.as_view() 儲存一系列資料(request、args、**kwargs等)給Book物件,然後都給dispatch進行路由分發。
dispatch乾的事:判斷請求方式是否支援,然後返回(通過getattr)支援的這些請求方法(get、post等,在檢視中自定義get、post的返回值)的結果。
c.通過dispatch就執行了CBV下請求方式的結果,返回結果
4.django原生的介面、序列化
六大基礎介面:獲取一個、獲取所有、增加一個、刪除一個、整體更新一個、區域性更新一個
十大介面:6大基礎、群增、群刪、整體群改、區域性群改
1.在應用的urls.py下分發路由 url(r'^books/$', views.Book.as_view()), #必須要加$,否則後面匹配不到 url(r'^books/(?P<pk>.*)/$', views.Book.as_view()),有名分組 在檢視函式中通過kwargs.get(pk)取到匹配的值
2.在views.py裡寫邏輯 class Book(View):
def get(self, request, *args, **kwargs): pk = kwargs.get('pk') #獲取引數 if not pk: #群查介面 #運算元據庫 book_obj_list = models.Book.objects.all() #序列化過程 book_list = [] for obj in book_obj_list: #將查到的物件序列化 dic = {} dic['title'] = obj.title dic['price'] = obj.price book_list.append(dic) return JsonResponse({ 'status' : 0, "msg" : "ok", "results": book_list, }, json_dumps_params={'ensure_ascii':False}) else: #單查介面 book_dic = models.Book.objects.filter(pk=pk).values( 'title', 'price').first() if book_dic: return JsonResponse({ 'status': 0, "msg": "ok", "results": book_dic, }, json_dumps_params={'ensure_ascii': False})
return JsonResponse({ 'status': 2, "msg": "no results", }, json_dumps_params={'ensure_ascii': False})
def post(self, request, *args, **kwargs): #前臺通過urlencoded方式提交資料 try: book_obj = models.Book.objects.create(**request.POST.dict()) #create建立物件。將request.POST中存放的提交的關鍵詞引數轉化為字典以**方式傳進去。沒傳引數,這邊會報錯。 if book_obj: return JsonResponse({ 'status': 0, "msg": "ok", “results”: {‘title’:book_obj.title, “price”:book_obj.price} }, json_dumps_params={'ensure_ascii': False}) except: #健壯性 return JsonResponse({ 'status': 1, "msg": "wrong params", }, json_dumps_params={'ensure_ascii': False}) return JsonResponse({ #可能運算元據庫失敗了 'status': 2, "msg": "created failed", }, json_dumps_params={'ensure_ascii': False})
|
JsonResponse返回時,中文會變成unicode,要加json_dumps_params={'ensure_ascii':False}選項。但在linux環境下的火狐瀏覽器,加了是亂碼。
filter返回queryset物件,物件裡是個列表(表名:物件資訊(有自定義str就是自定義的資訊))。first取裡第一個物件(相當於print(第一個物件))values展示對應的物件裡的值
<QuerySet [<Book: <<三國演義>>>]> #直接.filter
<<三國演義>> #.first()
<QuerySet [{'title': '三國演義', 'price': Decimal('56.00')}]> #.values('title','price')
{'title': '三國演義', 'price': Decimal('56.00')} #.values.first() 是個字典
上面序列化的工作很麻煩。drf就是為了方便序列化的。
postman可以完成不同方式的請求:get、post、put等
postman傳送資料包有三種方式:form-data、urlencoded、json. 原生django對urlencoded資料提交相容。