视图家族
1.generics:视图类
2.mixins:视图拓展类(工具类)
3.viewsets:视图集
视图层:
from rest_framework.generics import GenericAPIView from . import models, serializers from utils.response import APIResponse # 1.generics:视图类 class BooksGenericAPIView(GenericAPIView): queryset = models.Book.objects.filter(is_delete=False) serializer_class = serializers.BooksModelSerializer # lookup_field = 'pk' # 与urls中的有名分组,有名分组为pk这里可以省略 def get(self, request, *args, **kwargs): pk = kwargs.get('pk') if not pk: book_query = self.get_queryset() book_ser = self.get_serializer(book_query, many=True) return APIResponse(0, 'ok', book_ser.data) else: book_obj = self.get_object() book_ser = self.get_serializer(book_obj) return APIResponse(0, 'ok', book_ser.data) # 2.mixins:视图工具集 from rest_framework import mixins class BooksMixinsGenericAPIView(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericAPIView): queryset = models.Book.objects.filter(is_delete=False) serializer_class = serializers.BooksModelSerializer def get(self, request, *args, **kwargs): pk = kwargs.get('pk') if not pk: return self.list(request, *args, **kwargs) else: return self.retrieve(request, *args, **kwargs) # 整合mixins 到 generics 中:不需要自己写功能 from rest_framework.generics import ListCreateAPIView, RetrieveAPIView class BooksListAPIView(ListCreateAPIView): queryset = models.Book.objects.filter(is_delete=False) serializer_class = serializers.BooksModelSerializer #3. viewsets:视图集(整合mixins 到 generics)、 from rest_framework import viewsets class BooksGenericViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet): queryset = models.Book.objects.filter(is_delete=False) serializer_class = serializers.BooksModelSerializer def create_many_or_one(self, request, *args, **kwargs): request_data = request.data many = True if isinstance(request_data, list) else False book_ser = serializers.BooksModelSerializer(data=request_data, many=many) if book_ser.is_valid(): book_obj_list = book_ser.save() return APIResponse(0, 'ok', serializers.BooksModelSerializer(book_obj_list, many=many).data) else: return APIResponse(1, 'failed', book_ser.errors)
路由层:
from django.conf.urls import url, include from . import views urlpatterns = [ url(r'^v1/books/$', views.BooksGenericAPIView.as_view()), url(r'^v1/books/(?P<pk>d+)/', views.BooksGenericAPIView.as_view()), url(r'^v2/books/$', views.BooksMixinsGenericAPIView.as_view()), url(r'^v2/books/(?P<pk>d+)/', views.BooksMixinsGenericAPIView.as_view()), url(r'^v3/books/$', views.BooksListAPIView.as_view()), url(r'^v3/books/(?P<pk>d+)/', views.BooksListAPIView.as_view()), # 重点: url(r'^v4/books/$', views.BooksGenericViewSet.as_view({'get': 'list', 'post': 'create_many_or_one'})), url(r'^v4/books/(?P<pk>d+)/', views.BooksGenericViewSet.as_view({'get': 'retrieve'})), ] from rest_framework.routers import SimpleRouter #v4的另一种写法 router = SimpleRouter() router.register('v4/books', views.BooksGenericViewSet, base_name='book') #base_name='book'为反向解析 # print(router.get_urls()) # print(router.urls) urlpatterns.extend(router.urls)
认证组件
自定义认证类
from rest_framework.authentication import BaseAuthentication from rest_framework import exceptions class TokenAuthentication(BaseAuthentication): def authenticate(self, request): token = request._request.META.get('HTTP_TOKEN') # 前后台分离项目,认证字段通常为Token if token != '123321': raise exceptions.NotAuthenticated('认证失败') return None
settings.py
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( # 'rest_framework.authentication.SessionAuthentication', # 'rest_framework.authentication.BasicAuthentication', 'api.authentication.TokenAuthentication', #开启自定义类全局认证 ) }
视图层
from rest_framework import generics, viewsets, mixins from . import models, serializers class UsersRetrieveAPIView(generics.RetrieveAPIView): authentication_classes = () # 局部解除认证 queryset = models.User.objects.filter(is_delete=False) serializer_class = serializers.UsersModelSerializer from . import authentication class CarsGenericViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet): authentication_classes = (authentication.TokenAuthentication, ) # 局部开启认证 queryset = models.Car.objects.filter(is_delete=False) serializer_class = serializers.CarsModelSerializer
路由层
from django.conf.urls import url, include from . import views urlpatterns = [ url(r'^users/(?P<pk>d+)/', views.UsersRetrieveAPIView.as_view()), url(r'^cars/$', views.CarsGenericViewSet.as_view({'get': 'list'})), url(r'^cars/(?P<pk>d+)/', views.CarsGenericViewSet.as_view({'get': 'retrieve'})), ]