Django drf初級
web接口
# 請求工具:postman => https://www.getpostman.com/
# 接口:url鏈接,通過向鏈接發生不同的類型請求與數據得到相應的響應數據
# http://127.0.0.1:8888/test/
# https://api.map.baidu.com/place/v2/search
'''
ak: 6E823f587c95f0148c19993539b99295
region: 上海
query: 肯德基
output: json
'''
RESTful規范
# REST: 表征性狀態轉移(Representational State Transfer)
# RESTful規范:web數據請求接口設計規范
'''
1)通常使用https請求
2)域名:有api關鍵字出現
-- https://api.example.com (存在跨域問題)
-- https://example.com/api
3)版本:不同版本需要標注
-- https://example.com/api/v1 | -- https://example.com/api/1
-- https://example.com/api/v2 | -- https://example.com/api/2
4)資源:請求的目標數據稱之為資源,資源一般都有名詞復數表示
-- https://example.com/api/v1/books (之前不規范的案例: /get_books/)
5)操作方式:不從請求鏈接體現操作方式,從請求方式上決定操作方式
-- get:https://example.com/api/v1/books 獲取所有
-- post:https://example.com/api/v1/books 新增一本
-- put:https://example.com/api/v1/book/1 更新id=1的一本
-- patch:https://example.com/api/v1/book/1 更新id=1的一本
-- delete:https://example.com/api/v1/book/1 刪除id=1的一本
6)資源過濾:通過接口傳遞參數來過濾資源
-- https://example.com/api/v1/books?limit=10 限制10條
7)狀態碼:返回數據要標准狀態碼,通過在數據中 {"status": 200}
-- SUCCESS(0, "查詢成功")
-- NODATA(1, "非正確,無數據,顯示基本信息")
-- FEAILED(2, "查詢失敗")
8)錯誤信息:請求失敗需要標注錯誤信息 {"message": "請求參數不合法"}
9)操作結果:請求操作成功的返回結果 {"results": []}
-- get:返回資源列表 | 返回單一資源
-- post:返回單一新增資源
-- put:返回更新的資源
-- patch:返回更新的資源
-- delete:返回空文檔
10)子資源返回資源接口:返回的資源如果有子資源,返回子資源的鏈接地址,如查找書,書的封面圖片就可以url表示
'''
drf簡易書寫TESTful規范接口
# 路由層
from app import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^cbv/', views.CBVTest.as_view()),
url(r'^books/', views.books),
url(r'^book/(?P<id>\d+)/', views.book),
]
# 視圖層
from django.http import JsonResponse
book_list = [{'id': 1, 'name': '紅樓夢'}, {'id': 2, 'name': '水滸傳'}]
def books(request):
if request.method == "GET":
if 'ak' not in request.GET:
return JsonResponse({
'status': '101',
'msg': 'ak不存在'
}, json_dumps_params={'ensure_ascii': False})
ak = request.GET.get('ak')
if ak != '123abc':
return JsonResponse({
'status': '200',
'msg': 'ak非法'
}, json_dumps_params={'ensure_ascii': False})
return JsonResponse({
'status': '0',
'msg': 'ok',
'results': book_list
}, json_dumps_params={'ensure_ascii': False})
if request.method == 'POST':
name = request.POST.get('name')
id = len(book_list) + 1
book = {'id': id, 'name': name}
book_list.append(book)
return JsonResponse({
'status': '0',
'msg': 'ok',
'results': book
}, json_dumps_params={'ensure_ascii': False})
CBV源碼分析
# 視圖層
from django.shortcuts import render, HttpResponse
from django.views import View
class CBVTest(View):
# 通過調度(dispatch)分發請求
def dispatch(self, request, *args, **kwargs):
pass
super().dispatch(request, *args, **kwargs)
pass
def get(self, request):
return render(request, 'cbv.html')
def post(self, request):
return HttpResponse('cbv post method')
<!-- 模板層 -->
<form action="/cbv/" method="post">
{% csrf_token %}
<input type="text" name="usr">
<button type="submit">提交</button>
</form>
# 路由層
from app import views
urlpatterns = [
url(r'^cbv/', views.CBVTest.as_view()),
]
drf安裝與使用
# 1)安裝drf:pip3 install djangorestframework
# 2)settings.py注冊app:INSTALLED_APPS = [..., 'rest_framework']
# 3)基於cbv完成滿足RSSTful規范的接口
# 視圖層
from rest_framework.views import APIView
from rest_framework.response import Response
user_list = [{'id': 1, 'name': 'Bob'}, {'id': 2, 'name': 'Tom'}]
class Users(APIView):
def get(self, request, *args, **kwargs):
return Response({
'status': 0,
'msg': 'ok',
'results': user_list
})
def post(self, request, *args, **kwargs):
# request對formdata,urlencoded,json三個格式參數均能解析
name = request.data.get('name')
id = len(user_list) + 1
user = {'id': id, 'name': name}
user_list.append(user)
return Response({
'status': '0',
'msg': 'ok',
'results': user
})
# 路由層
from app import views
urlpatterns = [
url(r'^users/', views.Users.as_view()),
]
request源碼分析
# as_view()
# 核心走了父類as_view
view = super(APIView, cls).as_view(**initkwargs)
# 返回的是局部禁用csrf認證的view視圖函數
return csrf_exempt(view)
# dispatch(self, request, *args, **kwargs)
# 二次封裝request對象
request = self.initialize_request(request, *args, **kwargs)
# 自定義request規則
self.initial(request, *args, **kwargs)
# initialize_request(self, request, *args, **kwargs)
# 原生request封裝在request._request
# initial(self, request, *args, **kwargs)
# 認證
self.perform_authentication(request)
# 權限
self.check_permissions(request)
# 頻率
self.check_throttles(request)