DRF filters and sorts the process records of paging exception handling

Time:2021-12-29
catalogue
  • 1、 Filter
  • 2、 Sort
  • 3、 Pagination
    • PageNumberPagination
    • LimitOffsetPagination
    • CursorPagination
    • Inherit apiview usage
  • 4、 Exception handling
    • Source code analysis
    • How
  • 5、 Encapsulate the response object
    • summary

      1、 Filter

      To filter the list data by fields, you need to add Django filter module

      usage method:

      #1. Register and register settings in the app py
      INSTALLED_APPS = [
          'django_filters',
      ]
      
      # 2、settings. Py configuration
      REST_FRAMEWORK = {
          'DEFAULT_FILTER_BACKENDS': (
              'django_filters.rest_framework.DjangoFilterBackend',
          )
      }
      
      #3. Add a filter in the view_ The fields property specifies the filtered fields
      class BooksView(ModelViewSet):
          queryset = Books.objects.all()
          serializer_class = BooksSerializer
      
          filter_ Fields = ('title ',) # configure which fields can be filtered
          
      # http://127.0.0.1:8000/books/?title= The Dream of Red Mansion

      2、 Sort

      Sorting can use the orderingfilter provided by the rest framework to quickly indicate that the data is sorted by the specified field

      usage method:

      #1. First, set the filter in the view_ backends=[OrderingFilter]
      #2. Then add ordering in the view_ The fields property specifies the sort fields
      
      from rest_framework.filters import OrderingFilter
      class BooksView(ModelViewSet):
          queryset = Books.objects.all()
          serializer_class = BooksSerializer
      
          filter_ Backends = [orderingfilter] # step 1
          ordering_ Fields = ['price ','id'] # step 2
          
      # http://127.0.0.1:8000/books/?ordering=id Check whether there are fields indicating sorting through ordering, and sort by fields
      #- ID indicates that the ID fields are sorted in reverse order
      #ID indicates ascending sorting for the ID field

      3、 Pagination

      First, the rest framework provides three paging modes, and

      • PageNumberPagination
      • LimitOffsetPagination
      • CursorPagination

      Usage method 1: it can be inherited directly, but the configuration parameters need to be in settings Py configuration

      Usage 2: inherit the use of the parent pager through the subclass, and directly modify the parameters of the parent in the subclass (recommended)

      PageNumberPagination

      Properties in subclasses:

      • page_ Size: number of pages
      • page_ query_ Param: the number of pages sent by the front end. The default is “page”
      • page_ size_ query_ Param: number of pages sent by the front end; keyword name; none by default
      • max_ page_ Size: the maximum number of pages that can be set at the front end

      How to use:

      from rest_framework.generics import ListAPIView
      from rest_framework.pagination import PageNumberPagination
      from app01.models import Books
      from app01.ser import BooksSerializer
      
      #Step 1:
      class BookPageNumberPagination(PageNumberPagination):
          page_ Size = 3 # number of entries per page
          page_ query_ Param = 'page' # query the key of the page
          page_ size_ query_ Param = 'size' # number of items displayed on each page
          max_ page_ Size = 5 # maximum number of entries per page
      
      
      class BookView(ListAPIView):
          queryset = Books.objects.all()
          serializer_class = BooksSerializer
          
          #Step 2: paging configuration
          pagination_class = BookPageNumberPagination
          
          
      # url: http://127.0.0.1:8000/books/?page=1&size=5 Query page 1, showing five pieces of data in total

      LimitOffsetPagination

      Properties in subclasses:

      • default_ Limit: default limit. The default value is the same as page_ The size setting is consistent
      • limit_ query_ Param: limit parameter name. The default is’ limit ‘
      • offset_ query_ Param: offset parameter name, default ‘offset’
      • max_ Limit: the maximum limit. The default is none

      How to use:

      from rest_framework.generics import ListAPIView
      from rest_framework.pagination import LimitOffsetPagination
      from app01.models import Books
      from app01.ser import BooksSerializer
      
      #Step 1:
      class BookLimitOffsetPagination(LimitOffsetPagination):
          default_ Limit = 3 # pieces per page
          limit_ query_ Param = 'limit' # take a few later
          offset_ query_ Param = 'offset' # take several benchmarks from the first one
          max_ Limit = 5 # maximum number of entries per page
      
      
      class BookView(ListAPIView):
          queryset = Books.objects.all()
          serializer_class = BooksSerializer
          
          #Step 2: paging configuration
          pagination_class = BookLimitOffsetPagination
          
          
      # url: http://127.0.0.1:8000/books/?limit=3&offset=4 Start with the third item and then take four pieces of data

      CursorPagination

      Properties in subclasses:

      • cursor_ query_ Param: the default query field, which does not need to be modified
      • page_ Size: number of pages
      • Ordering: you need to specify the sort by

      How to use:

      Cursorpagination has a fast query speed, but it can’t locate the page. You can either look forward or look back.

      from rest_framework.generics import ListAPIView
      from rest_framework.pagination import CursorPagination
      from app01.models import Books
      from app01.ser import BooksSerializer
      
      #Step 1:
      class BookCursorPagination(CursorPagination):
          cursor_ query_ Param = 'cursor' # the key of each page query
          page_ Size = 3 # number of items displayed per page
          Ordering = 'ID' # sort field
      
      
      class BookView(ListAPIView):
          queryset = Books.objects.all()
          serializer_class = BooksSerializer
          
          #Step 2: paging configuration
          pagination_class = BookCursorPagination
          
          
      # url:http://127.0.0.1:8000/books/?cursor=cD0z

      Inherit apiview usage

      If you use methods 1 and 2, you need to inherit listapiview and configure it directly

      However, if the view class inherits genericapiview or apiview, you need to use another method:

      usage method:

      #1. Define a pager
      class BookPageNumberPagination(PageNumberPagination):
          page_ Size = 3 # number of entries per page
          page_ query_ Param = 'page' # query the key of the page
          page_ size_ query_ Param = 'size' # number of items displayed on each page
          max_ page_ Size = 5 # maximum number of entries per page
      
      
      class BookView(APIView):
      
          def get(self, request, *args, **kwargs):
              book_list = Books.objects.all()
      
              #2. Instantiate a pager object
              page_obj = BookPageNumberPagination()
              
              #3. Call paginate_ Queryset returns the data of each page
              book_list = page_obj.paginate_queryset(book_list, request, view=self)
      
              #4. Get the link from the previous page to the next page
              next_url = page_obj.get_next_link()
              previous_url = page_obj.get_previous_link()
      
              #5. Serialization
              book_ser = BooksSerializer(book_list, many=True)
              
              #6. Add to the response information
              data = {'next_url': next_url, 'previous_url': previous_url, 'data': book_ser.data}
              return Response(data=data)

      4、 Exception handling

      Exception handling is mainly used to unify interface returns

      Source code analysis

      Exception handling API in apiview_ The settings have been configured

      ‘EXCEPTION_HANDLER’: ‘rest_framework.views.exception_handler’,

      def exception_handler(exc, context):
          #First judge whether it is 404
          If isinstance (exc, http404): # exc is the exception object of exception information
              exc = exceptions.NotFound()
          #Then judge whether it is a permission problem
          elif isinstance(exc, PermissionDenied):
              exc = exceptions. Permissiondenied() # for example, a dictionary will be returned for permission problems
              
       #When judging whether you throw API exceptions - > authentication permissions, these are exceptions that inherit the API
          if isinstance(exc, exceptions.APIException):
              headers = {}
              if getattr(exc, 'auth_header', None):
                  headers['WWW-Authenticate'] = exc.auth_header
              if getattr(exc, 'wait', None):
                  headers['Retry-After'] = '%d' % exc.wait
      
              if isinstance(exc.detail, (list, dict)):
                  data = exc.detail
              else:
                  data = {'detail': exc.detail}
      
              set_rollback()
              return Response(data, status=exc.status_code, headers=headers)
          #As long as the above exceptions are handled
         
      
          Return none # means that Django will handle some exceptions if they are not handled

      How

      Because some dir exceptions are not handled, and Django’s handling does not meet our standards, we need to write a unified exception class to replace it and handle all situations. As long as the front-end exception sees something fixed.

      How to write:

      Rewrite a class, which is basically similar to it. When configuring, it is in settings Global configuration in PY

      #  app01_auth.py
      from rest_framework.views import exception_handler
      from rest_framework.response import Response
      
      def app01_exception_handler(exc, context):
          response = exception_ Handler (exc, context) # we also need to handle the original DRF
          #There are two cases. One is none, DRF does not handle it, and Django handles it, but the processing does not meet the requirements
          #The response object, DRF, handles what we need
      
      
          if not response:
              #If not, we'll deal with it ourselves
              return Response(data={'status': 400, 'error': str(exc)}, status=400)
          else:
              #After DRF has processed it, take out the information it processes and reprocess it
              return Response(data={'status': 400, 'error': response.data.get('detail')}, status=400)

      Then configure it globally: settings py

      
      REST_FRAMEWORK = {
          'EXCEPTION_HANDLER': 'app01.app_auth.app01_exception_handler',
      }
      

      5、 Encapsulate the response object

      class APIResponse(Response):
          def __ init__ (self, code = 100, MSG = 'success', data = none, status = none, headers = none, * * kwargs):
              
              dic = {'code': code, 'msg': msg}
              
              if  data:
                  dic = {'code': code, 'msg': msg,'data':data}
                  
              dic.update(kwargs)
              
              super().__init__(data=dic, status=status,headers=headers)
              
              
      #Use
      return APIResponse(data={"name":'xiaoyang'},token='dsafsdfa',aa='dsafdsfdee')
      return APIResponse(data={"name":'xiaoyang'})
      Return apiresponse (code ='101 ', MSG =' error ', data = {"name":' Xiaoyang '}, token ='dsafsdfa', AA ='dsafdee ', header = {})

      summary

      This is the end of this article on exception handling of DRF filtering sorting pages. For more information about DRF filtering sorting pages, please search the previous articles of developeppaer or continue to browse the relevant articles below. I hope you will support developeppaer in the future!