?
rest_framework-00-規范-APIview源碼解析-認證
規范
restframework教程?支付寶:
接口開發
訂單api----order
方式1:缺點:如果有10張表,則需要40個url.
?
urls.py
views.py
缺點:如果有10張表,則需要40個url.? ??接下來就出現了resrful 規范,比較簡潔
方式2:resrful 規范(建議)? url簡潔了,只有一條。
1. 根據method不同做不同的操作,示例:基于FBV:
?
?urls.py
views.py
?
2. 根據method不同做不同的操作,示例:基于CBV:
?urls.py:
views.py:
?
?
settings.py
運行結果:
代碼:
a. 接口開發urlpatterns = [# url(r'^admin/', admin.site.urls),url(r'^get_order/', views.get_order),url(r'^add_order/', views.add_order),url(r'^del_order/', views.del_order),url(r'^update_order/', views.update_order),]def get_order(request):return HttpResponse('')def add_order(request):return HttpResponse('')def del_order(request):return HttpResponse('')def update_order(request):return HttpResponse('')b. restful 規范(建議)1. 根據method不同做不同的操作,示例:基于FBV:urlpatterns = [url(r'^order/', views.order),]def order(request):if request.method == 'GET':return HttpResponse('獲取訂單')elif request.method == 'POST':return HttpResponse('創建訂單')elif request.method == 'PUT':return HttpResponse('更新訂單')elif request.method == 'DELETE':return HttpResponse('刪除訂單')基于CBV:urlpatterns = [url(r'^order/', views.OrderView.as_view()),]class OrderView(View):def get(self,request,*args,**kwargs):return HttpResponse('獲取訂單')def post(self,request,*args,**kwargs):return HttpResponse('創建訂單')def put(self,request,*args,**kwargs):return HttpResponse('更新訂單')def delete(self,request,*args,**kwargs):return HttpResponse('刪除訂單')
?
2.django rest framework規范有哪些?
10個規則:
1.https 、2.域名、3.版本、4.名詞、method請求方式、過濾條件、狀態碼、錯誤值、返回結果、Hypermedia API鏈接
注意:推薦使用CBV
- API與用戶的通信協議,總是使用HTTPs協議。
- 域名?
- https://api.example.com? ? ? ? ? ? ? ? ? ? ? ? ?盡量將API部署在專用域名(會存在跨域問題)
- https://example.org/api/? ? ? ? ? ? ? ? ? ? ? ? API很簡單
- 版本
- URL,如:https://api.example.com/v1/
- 請求頭? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 跨域時,引發發送多次請求
- 路徑,視網絡上任何東西都是資源,均使用名詞表示(可復數)
- https://api.example.com/v1/zoos
- https://api.example.com/v1/animals
- https://api.example.com/v1/employees
- method
- GET? ? ? :從服務器取出資源(一項或多項)
- POST? ? :在服務器新建一個資源
- PUT? ? ? :在服務器更新資源(客戶端提供改變后的完整資源)
- PATCH? :在服務器更新資源(客戶端提供改變的屬性)
- DELETE :從服務器刪除資源
- 過濾,通過在url上傳參的形式傳遞搜索條件
- https://api.example.com/v1/zoos?limit=10:指定返回記錄的數量
- https://api.example.com/v1/zoos?offset=10:指定返回記錄的開始位置
- https://api.example.com/v1/zoos?page=2&per_page=100:指定第幾頁,以及每頁的記錄數
- https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回結果按照哪個屬性排序,以及排序順序
- https://api.example.com/v1/zoos?animal_type_id=1:指定篩選條件
- 狀態碼
200 OK - [GET]:服務器成功返回用戶請求的數據,該操作是冪等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:用戶新建或修改數據成功。
202 Accepted - [*]:表示一個請求已經進入后臺排隊(異步任務)
204 NO CONTENT - [DELETE]:用戶刪除數據成功。
400 INVALID REQUEST - [POST/PUT/PATCH]:用戶發出的請求有錯誤,服務器沒有進行新建或修改數據的操作,該操作是冪等的。
401 Unauthorized - [*]:表示用戶沒有權限(令牌、用戶名、密碼錯誤)。
403 Forbidden - [*] 表示用戶得到授權(與401錯誤相對),但是訪問是被禁止的。
404 NOT FOUND - [*]:用戶發出的請求針對的是不存在的記錄,服務器沒有進行操作,該操作是冪等的。
406 Not Acceptable - [GET]:用戶請求的格式不可得(比如用戶請求JSON格式,但是只有XML格式)。
410 Gone -[GET]:用戶請求的資源被永久刪除,且不會再得到的。
422 Unprocesable entity - [POST/PUT/PATCH] 當創建一個對象時,發生一個驗證錯誤。
500 INTERNAL SERVER ERROR - [*]:服務器發生錯誤,用戶將無法判斷發出的請求是否成功。更多看這里:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
def get(self,request,*args,**kwargs):
ret = {
'code':1000,
'msg':'xxx'
}
# return HttpResponse(json.dumps(ret))
return HttpResponse(json.dumps(ret), status=201)
- 錯誤處理,狀態碼是4xx時,應返回錯誤信息,error當做key。
{error: "Invalid API key"
}
?
- 返回結果,針對不同操作,服務器向用戶返回的結果應該符合以下規范。
GET /collection:返回資源對象的列表(數組)
GET /collection/resource:返回單個資源對象
POST /collection:返回新生成的資源對象
PUT /collection/resource:返回完整的資源對象
PATCH /collection/resource:返回完整的資源對象
DELETE /collection/resource:返回一個空文檔
?
- Hypermedia API,RESTful API最好做到Hypermedia,即返回結果中提供鏈接,連向其他API方法,使得用戶不查文檔,也知道下一步應該做什么。
{"link": {"rel": "collection https://www.example.com/zoos","href": "https://api.example.com/zoos","title": "List of zoos","type": "application/vnd.yourformat+json"
}}
django rest framework框架
1.django rest framework框架的下載:
pip3 install djangorestframework
?
3.引出rest_framework
?
urls.py
?
?
views.py
?
?
?
?
?
2.APIview
?
APIView源碼:
1.APIView繼承了View
原生view
?2、APIView類里面有dispatch方法
3、 APIView在原有的基礎上,多了很多功能。request:進行了加工,是一個新的對象。
?
4.請求封裝request = self.initialize_request(request, *args, **kwargs)(版本、認證、權限、節流、解析器)
5.認證
?
6.如果自己寫了用戶認證,就找自己的認證方法:
?
?
7.加注釋、initial
8.initial
9.認證? ?
10.request是封裝后的對象了,所有user應該去APIView里面找。
11._authenticate??# 循環認證類的所有對象 [BasicAuthentication對象,]
?
?.authenticate方法檢查你是否已登入。如果用戶沒有登入則報錯。
12.接下來自己定義一個認證方法:必須有authenticate方法:如果用戶沒有登入,則報錯。
?
運行結果:url沒有傳token值,則認證失敗
url傳了token,認證成功
?
13.認證流程加注釋??
0.url.as_view? -》?1.self.dispatch? ?
self.dispatch
?2.initial(版本、認證、權限、節流、解析器)
?
3.perform_authentication 實現認證
4.?from rest_framework.request import Request? 方便查詢user
5.獲取認證對象,進行一步步的認證
?
?認證流程:view -> dispach -> 封裝Request -> initial:(版本、認證、權限、節流、解析器)-> perform_authentication 實現認證 -user -> authenticate方法
?
如果認證成功有(token值),request.user則有值。
?
?
認證代碼:
a. 認證 - 僅使用:from django.views import Viewfrom rest_framework.views import APIViewfrom rest_framework.authentication import BasicAuthenticationfrom rest_framework import exceptionsfrom rest_framework.request import Requestclass MyAuthentication(object):def authenticate(self,request):token = request._request.GET.get('token')# 獲取用戶名和密碼,去數據校驗if not token:raise exceptions.AuthenticationFailed('用戶認證失敗')return ("alex",None)def authenticate_header(self,val):passclass DogView(APIView):authentication_classes = [MyAuthentication,]def get(self,request,*args,**kwargs):print(request)print(request.user)ret = {'code':1000,'msg':'xxx'}return HttpResponse(json.dumps(ret),status=201)def post(self,request,*args,**kwargs):return HttpResponse('創建Dog')def put(self,request,*args,**kwargs):return HttpResponse('更新Dog')def delete(self,request,*args,**kwargs):return HttpResponse('刪除Dog')
?