restframework Component Details

Posted by wintallo on Wed, 18 Dec 2019 03:15:03 +0100

Introduction to restful
restful is an interface specification in which front-end and back-end interfaces are developed to improve team development efficiency, especially for front-end and back-end separation, according to which front-end and back-end development modules are not affected by each other
2. Routing

from rest_framework.routers import SimpleRouter,DefaultRouter

The routers module encapsulates a number of routing methods, the most basic of which is the BaseRouter class, which provides a custom interface
The following method gives you the ability to automatically generate two URLs with parameters
router = DefaultRouter() #Register Routes Inherits BaseRouter Class
router.register('user',UserProfileViewset,base_name='useruinfo')
router.register('menu',MenuProfileViewset,base_name='menuinfo')

Route mapping generated to view

3. view View
Help developers to provide classes and provide a variety of ways to use them. The following diagram shows the main classes provided and the inheritance relationships

Class introduction
1.APIView

class Nav(APIView):
"""
//Initialization Menu
"""
permission_classes = (permissions.IsAuthenticated, IsOwnerOrReadOnly)
authentication_classes = (JSONWebTokenAuthentication,)

def get(self,request):
    content = getMenu(request)
    if not content:
        return JsonResponse(data=content, code=200, msg="Menu initialization failed", flag=True)
    else:
        return JsonResponse(data=content, code=200, msg="Menu Initialized Successfully", flag=True)

Provide five methods of get,post,put,patch,delete
2.GenericAPIView

class IndexView(GenericAPIView):
queryset = models.UserInfo.objects.all()
serializer_class = UserInfoSerializer
lookup_field = 'pk'

def get(self,request,*args,**kwargs):
    pk = kwargs.get('pk')
    if pk:
        users = self.filter_queryset(queryset=models.UserInfo.objects.get(pk=pk))
        ser = self.get_serializer(instance=users)
    else:
        users = self.get_queryset()
        ser = self.get_serializer(instance=users,many=True)
    return Response(ser.data)

In GenericAPIView, it is not common to override some fields and methods
3.GenericViewSet

class IndexView(GenericViewSet):
serializer_class = UserInfoSerializer
queryset = models.UserInfo.objects.all()
def create(self,request,*args,**kwargs):
    pass

def list(self,request,*args,**kwargs):  # Get List Data
    users = models.UserInfo.objects.all()
    ser = UserInfoSerializer(instance=users,many=True)
    return Response(ser.data)

def retrieve(self,request,*args,**kwargs):  # Get Single Data
    pk = kwargs.get('pk')
    users = models.UserInfo.objects.get(pk=pk)
    ser = UserInfoSerializer(instance=users,many=False)
    return Response(ser.data)

def destroy(self,request,*args,**kwargs):
    pass

def update(self,request,*args,**kwargs):
    pass
    def partial_update(self,request,*args,**kwargs):
            pass

This class inherits ViewSetMixin, generics.GenericAPIView, where the as_view() method is overridden in ViewSetMixin, so you can bind the way requests are made in URL s to view functions and exist as key-value pairs in urls.py

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import  views
    urlpatterns = [
        # url(r'^admin/', admin.site.urls),
        url(r'^hehe/', views.hehe),
        url(r'^index/$', views.IndexView.as_view({'get':'list','post':'create'})),
        url(r'^index/(?P<pk>\d+)/$', views.IndexView.as_view({'get':'retrieve','put':'update','patch':'partial_update','delete':'destroy'})),]

4.ModelViewSet
ModelViewSet inherits four mixed classes and a generic class, and will get all the methods for addition, deletion, and modification checks

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

4. Certification
rest_framework provides us with authenticated interfaces, which are provided by the BaseAuthentication class, as well as some encapsulated authentication classes
The interface function authticate authentication successfully returned tuples (user, token) assigned to request.user and request.auth, respectively.

class Auth(BaseAuthentication):
def authenticate(self, request):
    token = request.query_params.get('token')
    obj = models.Token.objects.filter(token=token).first()
    if not obj:
        raise AuthenticationFailed({'code': 1001, 'error': 'Authentication Failure'})
    return (obj.user.username, obj)

There are many authentication methods, you can use jwt authentication

from rest_framework_jwt.authentication import JSONWebTokenAuthentication
class UserProfileViewset(custom_viewset_base.CustomViewBase):
"""
permission_classes,authentication_classes Placement order cannot be changed

"""
permission_classes = (IsOwnerOrReadOnly,)
    authentication_classes = (JSONWebTokenAuthentication, authentication.SessionAuthentication)
serializer_class = UserProfileSerializer
queryset = User.objects.all()
pagination_class = custom_pagination.LargeResultsSetPagination
filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
filter_class = UserProfileFilter
search_fields = ('username', )  # What does ^ start with, = equal to match'u all_u'
ordering_fields = ('username',)  # sort
ordering = ('username',)  # sort field

5. Permissions
The interface functions provided by the BasePermission class are has_permission and has_object_permission

class BasePermission(object):
"""
A base class from which all permission classes should inherit.
"""

def has_permission(self, request, view):
    """
    Return `True` if permission is granted, `False` otherwise.
    """
    # Write our permission logic here
    return True

def has_object_permission(self, request, view, obj):
    """
    Return `True` if permission is granted, `False` otherwise.
    """
    return True

This method can be overridden to control access rights

6. Serialization
Serialization of queryset and validation of request data format.
Typically inherits two classes, Serializer and ModelSerializer
Each field serialized by Serializer has its own ModelSerializer which renders all fields based on the database table

class CourseDetailModelSerializers(serializers.ModelSerializer):
title = serializers.CharField(source='course.name')
img = serializers.ImageField(source='course.course_img')
level = serializers.CharField(source='course.get_level_display')
recommends = serializers.SerializerMethodField()
chapters = serializers.SerializerMethodField()

def get_recommends(self, obj):
    queryset = obj.recommend_courses.all()
    return [{'id': row.id, 'title': row.name} for row in queryset]

def get_chapters(self, obj):
    queryset = obj.course.course_chapters.all()
    return [{'id': row.id, 'name': row.name} for row in queryset]

class Meta:
    model = CourseDetail
    fields = ['course', 'title', 'img', 'level', 'why_study', 'chapters', 'recommends']

7. Paging
Custom Paging
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination
from collections import OrderedDict
from rest_framework.response import Response

class LargeResultsSetPagination(PageNumberPagination):
page_size = 10 #default number of bars per page
page_size_query_param = "page_size" #Display the number of bars per page parameter string
page_query_param = "page" #Show which page of data passed
max_page_size = 100 #maximum page number

def get_paginated_response(self, data):
    code = 200
    msg = 'query was successful'
    if not data:
        code = 200
        msg = "Data is empty"

    return Response(OrderedDict([
        ('code', code),
        ('msg', msg),
        ('flag', True),
        ('count', self.page.paginator.count),
        ('next', self.get_next_link()),
        ('previous', self.get_previous_link()),
        ('results', data)
    ]))

Introducing in view
pagination_class = LargeResultsSetPagination

8. Filters
Using the django_filters module

import django_filters

from user.models import *

class UserProfileFilter(django_filters.rest_framework.FilterSet):
"""
Filter users
"""
#id = django_filters.NumberFilter(field_name="id",lookup_expr="exact") #Exact match
username = django_filters.CharFilter(field_name="username",lookup_expr="contains")
#name = django_filters.CharFilter(field_name="name", lookup_expr="contains")
#mobile = django_filters.CharFilter(field_name="mobile", lookup_expr="contains")

class Meta:
    model = UserProfile
    fields = ["username"]

view View Application
filter_class = UserProfileFilter

9. Renderers
The default two renderers are Json's and rest_framework's own templates accessed in a browser

Topics: Web Development Django Mobile Database JSON