django rest frameworkcss
API與用戶的通訊協議,老是使用HTTPs協議。html
restful 規範(10):python
按url來記,從左到右, 而後發送請求,在返回響應面試
1. 根據method不一樣,進行不一樣操做 6 GET/POST/PUT/DELETE/PATCH 2. 面向資源編程 4 使用名詞表示資源 http://www.luffycity.com/salary 3. 體現版本 3 http://www.luffycity.com/v1/salary http://www.luffycity.com/v2/salary https://v4.bootcss.com/ https://v3.bootcss.com/ 4. 體現是API 2 http://www.luffycity.com/api/v1/salary http://www.luffycity.com/api/v2/salary http://api.luffycity.com/v1/salary http://api.luffycity.com/v2/salary 5. https 1 https://www.luffycity.com/api/v1/salary https://www.luffycity.com/api/v2/salary 6. 響應式設置狀態碼 8 200 300 400 500 return HttpResponse('adfasdf',status=300) 7. 條件 5 https://www.luffycity.com/api/v2/salary?page=1&size=10 8. 返回值 7 https://www.luffycity.com/api/v2/salary GET: 全部列表 { code: 10000, data: [ {'id':1,'title':'高亮'}, {'id':1,'title':'龍泰'}, {'id':1,'title':'小東北'}, ] } POST: 返回新增的數據 {'id':1,'title':'高亮'} https://www.luffycity.com/api/v2/salary/1/ GET: 獲取單條數據 {'id':1,'title':'高亮'} PUT:更新 {'id':1,'title':'高亮'} PATCH: 局部更新 {'id':1,'title':'高亮'} DELETE:刪除 9. 返回錯誤信息 9 { code: 100001, error: 'xxx錯誤' } 10. Hypermedia API 10 ret = { code: 1000, data:{ id:1, name:'小強', depart_id:http://www.luffycity.com/api/v1/depart/8/ } } 建議你們使用restful規範
摘自:http://www.ruanyifeng.com/blog/2014/05/restful_api.html django
django rest framework框架的做用:編程
--->>> 基於這個組件來幫助咱們快速的開發符合restful規範的接口,它是Django裏面的一個組件,這個組件爲咱們提供瞭如下的功能: - 權限 - 認證 - 訪問頻率限制 - 序列化 把queryset數據轉變爲json數據給用戶返回. - 路由 - 視圖 面試題:你的寫的類都繼承過哪些類? class View(object): class APIView(View): class GenericAPIView(views.APIView): class GenericViewSet(ViewSetMixin, generics.GenericAPIView) # ViewSetMixin 是對as_view裏面的參數進行處理 class ModelViewSet(mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, mixins.ListModelMixin, GenericViewSet): - 分頁 - 解析器 - 渲染器 - 版本 按照HTTP請求的生命週期去記; 先是進入路由,在視圖,進入dispatch()裏面,然 後提供的是版本,權限,認證,頻率,而後從 解析器()裏面取數據,再序列化,分頁,渲染器。
路由系統:json
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^books$', views.BookView.as_view(),name='books')]
視圖函數CBV:api
class BookView(APIView): # def get(self,request): # book_list = Book.objects.all() # # #序列化方式1: 取全部的字段,封裝爲 列表裏面套 字典的形式 # # from django.forms.models import model_to_dict # # # # data=[] # # for obj in book_list: # # data.append(model_to_dict(obj)) # # print(data) # # 序列化方式2: 跟第一種差很少。 # # data = serializers.serialize("json", book_list) # # return HttpResponse(data) # # 序列化方式3: # bs = BookModelSerializers(book_list, many=True,context={'request': request}) # return Response(bs.data) def get(self,request): return RequestView(Book,BookModelSerializers,self).get(request) def post(self,request): # print(request.data) #獲得提交的數據,是一個對象 # bs = BookModelSerializers(data=request.data) # many=True是序列化一個querset對象的一個列表; # if bs.is_valid(): # print(bs.validated_data) # bs.save() # return Response(bs.data) # else: # return Response(bs.errors)
django rest framework的源碼流程restful
按照上面的代碼分析:網絡
1.當咱們訪問請求的時候,將會執行路由系統中的views.BookView.as_view()
2.當前咱們本身寫的這個類沒有as_view()方法,所以會找父類的as_view()方法;即在APIView的as_view()方法
super(APIView,cls)------>爲當前父類(view)
super(APIView,cls) 首先找到 APIView的父類(就是類view),而後把 APIView類轉換爲 view類;
super(APIView,self)------>爲當前父類(view)的對象;
3.執行父類view下的as_view()方法:
即經過上面的源碼能夠知道,當請求來的時候,首先會執行 當前調用as_view()方法的這個類的dispatch方法。
因爲咱們本身沒有寫dispatch方法,因此會調用父類的APIView下面的dispatch方法。
4.執行APIView下面的dispatch方法
5.具體執行self.initialize_request(request, *args, **kwargs)的方法
initialize_request是APIView類裏面的一個方法,從新封裝了request對象,增長了一些屬性信息
認證信息。主要經過APIView類中的get_authenticators(rest_framework/views.py)方法獲取,這個方法會返回一個全部認證對象的列表
在全局定義的
DEFAULT_AUTHENTICATION_CLASSES
authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
咱們本身也能夠在本身寫的這個views.BookView下自定製一個類屬性
authentication_classes=[TokenAuth,]
TokenAuth
from rest_framework import exceptions from rest_framework.authentication import BaseAuthentication from .models import * class TokenAuth(BaseAuthentication): def authenticate(self, request): token = request.GET.get("token") token_obj = Token.objects.filter(token=token).first() if not token_obj: raise exceptions.AuthenticationFailed("驗證失敗123!") else: return token_obj.user.pk, token_obj.token # def authenticate_header(self, request): # pass # 只是咱們繼承了BaseAuthentication的認證組件 就不用寫了。
默認的認證配置信息是在rest_framework/settings.py文件中定義的
6.dispatch中的initialize_request方法執行完成以後,還有執行一個重要方法是self.initial(request, *args, **kwargs),這個方法也是APIView類裏的。在這個方法裏面初始化
被從新封裝的request對象
實現功能:
版本組件:
執行self.determine_version(request, *args, **kwargs)的結果返回的是一個元組(版本號,版本對象)
版本放在url 裏面的用這個類
from rest_framework.versioning import URLPathVersioning
版本放在url 後面做爲參數的用這個類
from rest_framework.versioning import QueryParameterVersioning
設置版本及獲取版本
a. 基於url的get傳參方式
REST_FRAMEWORK = { 'DEFAULT_VERSION': 'v1', # 默認版本 'ALLOWED_VERSIONS': ['v1', 'v2'], # 容許的版本 'VERSION_PARAM': 'version' # URL中獲取值的key }
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.versioning import QueryParameterVersioning class TestView(APIView): versioning_class = QueryParameterVersioning def get(self, request, *args, **kwargs): # 獲取版本 print(request.version) # 獲取版本管理的類 print(request.versioning_scheme) # 反向生成URL reverse_url = request.versioning_scheme.reverse('test', request=request) print(reverse_url) return Response('GET請求,響應內容') def post(self, request, *args, **kwargs): return Response('POST請求,響應內容') def put(self, request, *args, **kwargs): return Response('PUT請求,響應內容')
認證組件:
執行APIView裏面的perform_authentication方法,該方法返回request.user,則會調用新封裝的Request對象裏面的user方法。在user方法裏面最終調用了Request類裏面的_authenticate方法
執行rest_framework.request.Request類中的_authenticate方法,這個方法會遍歷認證類,並根據認證結果給self.user, self.auth賦值。因爲user,和auth都有property屬性,
因此給賦值的時候先在先執行setter方法
self.authenticators就是包含當前類下面全部的認證組件類的對象的一個列表。遍歷列表,執行 對象.authenticate()。
authenticate方法的返回值爲一個元組(user_auth_tuple)
self.user,self.auth=user_auth_tuple
上面其餘兩個 權限;訪問頻率限制的原理跟認證是同樣的。
7.dispatch中的initial方法執行完以後,會繼續判斷request.method並執行method相應的method.
8.執行BookView中定義的請求方法,返回數據
rest framework組件爲咱們提供了下面的這些功能: 按照HTTP請求的生命週期去記; 先是進入路由,在視圖,進入dispatch()裏面,然 後提供的是版本,權限,認證,頻率,而後從 解析器()裏面取數據,再序列化,分頁,渲染器。