一、APIView
通过APIView实现API的过程如下:
urls.py
url(r'^books/$', views.BookView.as_view(),name="books"),
url(r'^books/(\d+)/$', views.BookDetailView.as_view(),name="detailbook"),
views.py
class BookView(APIView):
def get(self, request):
book_list = Book.objects.all()
bs = BookModelSerializers(book_list, many=True, context={'request': request})
return Response(bs.data) def post(self, request):
# post请求的数据
bs = BookModelSerializers(data=request.data)
if bs.is_valid():
print(bs.validated_data)
bs.save() # create方法
return Response(bs.data)
else:
return Response(bs.errors) class BookDetailView(APIView): def get(self, request, id): book = Book.objects.filter(pk=id).first()
bs = BookModelSerializers(book, context={'request': request})
return Response(bs.data) def put(self, request, id):
book = Book.objects.filter(pk=id).first()
bs = BookModelSerializers(book, data=request.data, context={'request': request})
if bs.is_valid():
bs.save()
return Response(bs.data)
else:
return Response(bs.errors) def delete(self, request, id):
Book.objects.filter(pk=id).delete() return Response()
urls中,定义了两个url的请求方式:
通过URL:http://127.0.0.1/books/ GET/POST数据
通过URL:http://127.0.0.1/books/id/ GET/PUT/DELETE数据
第一种,url(r'^books/$', views.BookView.as_view(),name="books"),调用过程如下:
views.BookView.as_view()
1、APIView.as_view(),返回view,实际上是执行View.as_view()
2、View中的as_view()返回disptch()函数
3、self会从View类往上找dispatch(),在APIView类中有找到dispatch()
4、dispatch()会找get、post、put、delete等方法
5、在当前View下,BookView类下定义了get、post,BookDetailView类下定义了get、put、delete
6、执行当前类下的对应方法
第二种URL执行过程一样。
二、ModelView
通过ModelView实现API过程如下:
urls.py
url(r'^authors/$', views.AuthorModelView.as_view({'get':'list','post':'create'}),name="authors"),
url(r'^authors/$', views.AuthorModelView.as_view({'get':'retrieve','post':'update','delete':'destory'}),name="authors"),
views.py
class AuthorModelView(viewsets.ModelViewSet):
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers
执行过程如下:
1、当前类下没有as_view方法,从父类ModelViewSet中查找
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `create()`, `retrieve()`, `update()`,
`partial_update()`, `destroy()` and `list()` actions.
"""
pass
2、ModeViewSet在mixins中没有as_view,从GenericViewSet往上找
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
"""
The GenericViewSet class does not provide any actions by default,
but does include the base set of generic view behavior, such as
the `get_object` and `get_queryset` methods.
"""
pass
3、从ViewSetMixin中找到了as_view(),实际上返回了dispatch()
ViewSetMixin==>generics.GenericAPIView==>views.APIView==>dispatch()
4、执行dispatch(),实际上是找get、post、put、delete等方法
5、在当前类下找到对应的方法
三、认证、权限、频率源码
通过ModelView方式实现认证,
局部应用:
class AuthorModelView(viewsets.ModelViewSet): authentication_classes = [TokenAuth, ]
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers
pagination_class = StandardResultsSetPagination
全局应用:
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.utils.TokenAuth",], }
源码实现过程:
服务端以authors为例:
1、在AuthorModelView中查找as_view(),在本类中找不到,往上查找;
2、父类:viewsets.ModelViewSet
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `create()`, `retrieve()`, `update()`,
`partial_update()`, `destroy()` and `list()` actions.
"""
pass
3、其他几个父类没有as_view()和祖父类了,只能从GenericViewSet往上找;
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
"""
The GenericViewSet class does not provide any actions by default,
but does include the base set of generic view behavior, such as
the `get_object` and `get_queryset` methods.
"""
pass
4、最左边父类ViewSetMixin查找as_view(),找到了
5、ViewSetMixin中的as_veiw()实际上返回了dispatch()
6、再查找dispatch()方法,顺序:generics.GenericAPIView==>APIView==>dispatch()
def dispatch(self, request, *args, **kwargs):
"""
`.dispatch()` is pretty much the same as Django's regular dispatch,
but with extra hooks for startup, finalize, and exception handling.
"""
self.args = args
self.kwargs = kwargs
request = self.initialize_request(request, *args, **kwargs)
self.request = request
self.headers = self.default_response_headers # deprecate? try:
self.initial(request, *args, **kwargs) # Get the appropriate handler method
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed response = handler(request, *args, **kwargs) except Exception as exc:
response = self.handle_exception(exc) self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
7、dispatch()中,先会执行self.initial()
def initial(self, request, *args, **kwargs):
"""
Runs anything that needs to occur prior to calling the method handler.
"""
self.format_kwarg = self.get_format_suffix(**kwargs) # Perform content negotiation and store the accepted info on the request
neg = self.perform_content_negotiation(request)
request.accepted_renderer, request.accepted_media_type = neg # Determine the API version, if versioning is in use.
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme # Ensure that the incoming request is permitted
self.perform_authentication(request)
self.check_permissions(request)
self.check_throttles(request)
8、initial()中会对过来的请求进行认证、授权、频率检测。
图标流程如下: