068. Using DRF view set of Python framework Django

Keywords: Django vim Database MySQL

One view atlas and the use of routing

Using the view set ViewSet, you can place a series of logically related actions into a class:

  • list() provides a set of data

  • retrieve() provides a single data

  • create() create data

  • update() to save the data

  • Destroy() delete data

The ViewSet view set class no longer implements methods such as get(), post(), but implements action s such as list(), create().

The view set will only map the action action to the specific request mode when using the as? View() method.

1.1 common view set parent classes

1 ViewSet

  • The functions inherited from APIView and ViewSetMixin are basically similar to those of APIView, providing identity authentication, permission verification, traffic management, etc.
  • ViewSet implements the mapping processing of the dictionary (such as {'get':'list'}) when calling as ﹐ view(), mainly by inheriting ViewSetMixin.
  • In the ViewSet, there is no action method provided. We need to implement the action method ourselves.

2 GenericViewSet

It is usually not convenient to use the ViewSet, because the list, retrieve, create, update, destory and other methods need to be written by ourselves, and these methods have the same name as the methods provided by the Mixin extension class mentioned earlier, so we can reuse these methods by inheriting the Mixin extension class without writing by ourselves. But the Mixin extension class depends on GenericAPIView, so you also need to inherit GenericAPIView.

GenericViewSet helps us to complete such inheritance work. It inherits from GenericAPIView and ViewSetMixin. It implements the mapping processing work of the dictionary (such as {'get':'list '}) passed in when calling as 「 view(), and also provides the basic method provided by GenericAPIView, which can be directly used with Mixin extension classes.

3.ModelViewSet

Inherited from GenericViewSet, including ListModelMixin, RetrieveModelMixin, CreateModelMixin, UpdateModelMixin, DestoryModelMixin.

4.ReadOnlyModelViewSet

Inherited from GenericViewSet, including ListModelMixin and RetrieveModelMixin.

1.2 preliminary use of view set

Create a sub app app

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# python3 manage.py startapp collect

register

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'students.apps.StudentsConfig',
    'ser.apps.SerConfig',
    'req.apps.ReqConfig',
    'collect.apps.CollectConfig',
]

Routing distribution

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('student/',include("students.urls")),
    path('ser/',include("ser.urls")),
    path('req/', include("req.urls")),
    path('collect/', include("collect.urls")),
]

Routing configuration

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# vim collect/urls.py

from  django.urls import path,re_path
from collect import views

urlpatterns = [
    path('student1/', views.Student1ViewSet.as_view({"get": "get_5"})),
]

Serialized file

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# vim collect/serializers.py 

from students.models import Student
from rest_framework import serializers


class StudentModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = Student
        fields = ["id", "name", "age", "sex"]
        extra_kwargs = {
            "name": {"max_length": 10, "min_length": 4},
            "age": {"max_value": 150, "min_value": 0},
        }

    def validate_name(self, data):
        if data == "root":
            raise serializers.ValidationError("User name cannot be root!")
        return data

    def validate(self, attrs):
        name = attrs.get('name')
        age = attrs.get('age')

        if name == "alex" and age == 22:
            raise serializers.ValidationError("alex The story at 22...")

        return attrs

view file

from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer

from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #Remove all,Parallel slice operation
        queryset = Student.objects.all()[:5]
        #instantiation 
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)

Visit http://127.0.0.1:8000/collect/student1/ to get five pieces of data

Data in database

mysql> select * from tb_student;

Change the sex with id=5 to false

Database existing data

Get data for five men

from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer

from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #Remove all,Parallel slice operation
        queryset = Student.objects.all()[:5]
        #instantiation 
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    def get_5_female(self,request):
        queryset = Student.objects.filter(sex=False)[:5]
        serializer = StudentModelSerializer(instance=queryset, many=True)
        return Response(serializer.data)

Configure routing

Do not write two http requests with the same key in the as view of the same route, which will result in overwrite!!!

from  django.urls import path,re_path
from collect import views

urlpatterns = [
    path('student1/', views.Student1ViewSet.as_view({"get": "get_5"})),
    path('student1/get_5_female/', views.Student1ViewSet.as_view({"get": "get_5_female"})),
]

Visit http://127.0.0.1:8000/collect/student1/get ﹐ 5 ﹐ normal / and the results are as follows

 

Get one

from  django.urls import path,re_path
from collect import views

urlpatterns = [
    #ViewSet
    path('student1/', views.Student1ViewSet.as_view({"get": "get_5"})),
    path('student1/get_5_female/', views.Student1ViewSet.as_view({"get": "get_5_female"})),
    re_path(r'^student1/(?P<pk>\d+)/$', views.Student1ViewSet.as_view({"get": "get_one"})),
]

Configuration view

from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer

from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #Remove all,Parallel slice operation
        queryset = Student.objects.all()[:5]
        #instantiation 
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    def get_5_female(self,request):
        queryset = Student.objects.filter(sex=False)[:5]
        serializer = StudentModelSerializer(instance=queryset, many=True)
        return Response(serializer.data)
    def get_one(self,request,pk):
        student_obj = Student.objects.get(pk=pk)
        serializer = StudentModelSerializer(instance=student_obj)
        return Response(serializer.data)

POSTMAN debugging, visit http://127.0.0.1:8000/collect/student1/5/

 

GenericViewSet view

URL routing configuration

from  django.urls import path,re_path
from collect import views

urlpatterns = [
    #ViewSet
    path('student1/', views.Student1ViewSet.as_view({"get": "get_5"})),
    path('student1/get_5_female/', views.Student1ViewSet.as_view({"get": "get_5_female"})),
    re_path(r'^student1/(?P<pk>\d+)/$', views.Student1ViewSet.as_view({"get": "get_one"})),
    # GenericViewSet
    path('student2/', views.Student3GenericViewSet.as_view({"get": "get_5"})),
    path('student2/get_5_female/', views.Student3GenericViewSet.as_view({"get": "get_5_female"})),
]

view file

from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer
from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #Remove all,Parallel slice operation
        queryset = Student.objects.all()[:5]
        #instantiation 
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    def get_5_female(self,request):
        queryset = Student.objects.filter(sex=False)[:5]
        serializer = StudentModelSerializer(instance=queryset, many=True)
        return Response(serializer.data)
    def get_one(self,request,pk):
        student_obj = Student.objects.get(pk=pk)
        serializer = StudentModelSerializer(instance=student_obj)
        return Response(serializer.data)

from rest_framework.viewsets import GenericViewSet
class Student3GenericViewSet(GenericViewSet):
    serializer_class = StudentModelSerializer
    queryset = Student.objects.all()
    def get_5(self, request):
        student_list = self.get_queryset()[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)
    def get_5_female(self, request):
        student_list = self.get_queryset().filter(sex=False)[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)

POSTMAN debugging

1.3 GenericViewSet combined model class

Can be combined with model classes to quickly generate basic API interfaces

url routing configuration

from  django.urls import path,re_path
from collect import views

urlpatterns = [
    #ViewSet
    path('student1/', views.Student1ViewSet.as_view({"get": "get_5"})),
    path('student1/get_5_female/', views.Student1ViewSet.as_view({"get": "get_5_female"})),
    re_path(r'^student1/(?P<pk>\d+)/$', views.Student1ViewSet.as_view({"get": "get_one"})),
    # GenericViewSet
    path('student2/', views.Student3GenericViewSet.as_view({"get": "get_5"})),
    path('student2/get_5_female/', views.Student3GenericViewSet.as_view({"get": "get_5_female"})),
    # GenericViewSet Combined with model class to generate basic API Interface,When using get,trigger list Method of,When using POST request,trigger create Method
    path("students3/", views.Student4GenericViewSet.as_view({"get": "list", "post": "create"})),
]

view file

from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer

from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #Remove all,Parallel slice operation
        queryset = Student.objects.all()[:5]
        #instantiation 
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    def get_5_female(self,request):
        queryset = Student.objects.filter(sex=False)[:5]
        serializer = StudentModelSerializer(instance=queryset, many=True)
        return Response(serializer.data)
    def get_one(self,request,pk):
        student_obj = Student.objects.get(pk=pk)
        serializer = StudentModelSerializer(instance=student_obj)
        return Response(serializer.data)

from rest_framework.viewsets import GenericViewSet
class Student3GenericViewSet(GenericViewSet):
    serializer_class = StudentModelSerializer
    queryset = Student.objects.all()
    def get_5(self, request):
        student_list = self.get_queryset()[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)
    def get_5_female(self, request):
        student_list = self.get_queryset().filter(sex=False)[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)
    
from rest_framework.mixins import ListModelMixin, CreateModelMixin
class Student4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

POSTMAN debugging

get request

POST request

 

View database

 

1.4 ModelViewSet configuration

url configuration

from  django.urls import path,re_path
from collect import views

urlpatterns = [
    #ViewSet
    path('student1/', views.Student1ViewSet.as_view({"get": "get_5"})),
    path('student1/get_5_female/', views.Student1ViewSet.as_view({"get": "get_5_female"})),
    re_path(r'^student1/(?P<pk>\d+)/$', views.Student1ViewSet.as_view({"get": "get_one"})),
    # GenericViewSet
    path('student2/', views.Student3GenericViewSet.as_view({"get": "get_5"})),
    path('student2/get_5_female/', views.Student3GenericViewSet.as_view({"get": "get_5_female"})),
    # GenericViewSet Combined with model class to generate basic API Interface
    path("student3/", views.Student4GenericViewSet.as_view({"get": "list", "post": "create"})),
    # ModelViewSet 5 are provided by default API Interface
    path("student4/", views.Student5ModelViewSet.as_view({"post": "create", "get": "list"})),
    re_path(r"^student4/(?P<pk>\d+)/$",
            views.Student5ModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
]

views

from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer

from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #Remove all,Parallel slice operation
        queryset = Student.objects.all()[:5]
        #instantiation 
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    def get_5_female(self,request):
        queryset = Student.objects.filter(sex=False)[:5]
        serializer = StudentModelSerializer(instance=queryset, many=True)
        return Response(serializer.data)
    def get_one(self,request,pk):
        student_obj = Student.objects.get(pk=pk)
        serializer = StudentModelSerializer(instance=student_obj)
        return Response(serializer.data)

from rest_framework.viewsets import GenericViewSet
class Student3GenericViewSet(GenericViewSet):
    serializer_class = StudentModelSerializer
    queryset = Student.objects.all()
    def get_5(self, request):
        student_list = self.get_queryset()[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)
    def get_5_female(self, request):
        student_list = self.get_queryset().filter(sex=False)[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)

from rest_framework.mixins import ListModelMixin, CreateModelMixin
class Student4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ModelViewSet
class Student5ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

POSTMAN debugging

Get all

POST add

data base

PUT modification

data base

Delete delete

 

data base

mysql> select * from tb_student;
+----+------------+-----+-----+------------+-------------------+
| id | name       | sex | age | class_null | description       |
+----+------------+-----+-----+------------+-------------------+
|  1 | linghu chong     |   1 |  18 | 205        | hello mysqlf      |
|  2 | ren woxing     |   1 |  55 | 203        | hello let me go   |
|  3 | li xunguan     |   1 |  33 | 207        | be happy lee      |
|  5 | limochu    |   0 |  36 | 208        | Don't Worry Lee   |
|  6 | mchaofeng  |   1 |  26 |            |                   |
|  7 | yangguo    |   1 |  25 |            |                   |
|  8 | xiaolongnv |   0 |  25 |            |                   |
+----+------------+-----+-----+------------+-------------------+

1.5 ReadOnlyModelViewSet configuration

url routing configuration

from  django.urls import path,re_path
from collect import views

urlpatterns = [
    #ViewSet
    path('student1/', views.Student1ViewSet.as_view({"get": "get_5"})),
    path('student1/get_5_female/', views.Student1ViewSet.as_view({"get": "get_5_female"})),
    re_path(r'^student1/(?P<pk>\d+)/$', views.Student1ViewSet.as_view({"get": "get_one"})),
    # GenericViewSet
    path('student2/', views.Student3GenericViewSet.as_view({"get": "get_5"})),
    path('student2/get_5_female/', views.Student3GenericViewSet.as_view({"get": "get_5_female"})),
    # GenericViewSet Combined with model class to generate basic API Interface
    path("student3/", views.Student4GenericViewSet.as_view({"get": "list", "post": "create"})),
    # ModelViewSet 5 are provided by default API Interface
    path("student4/", views.Student5ModelViewSet.as_view({"post": "create", "get": "list"})),
    re_path(r"^student4/(?P<pk>\d+)/$",
            views.Student5ModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
    # ReadOnlyModelViewSet
    path("student5/", views.Student6ReadOnlyModelViewSet.as_view({"get": "list"})),
    re_path(r"^student5/(?P<pk>\d+)/$", views.Student6ReadOnlyModelViewSet.as_view({"get": "retrieve"})),
]

View view configuration

from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer

from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #Remove all,Parallel slice operation
        queryset = Student.objects.all()[:5]
        #instantiation 
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    def get_5_female(self,request):
        queryset = Student.objects.filter(sex=False)[:5]
        serializer = StudentModelSerializer(instance=queryset, many=True)
        return Response(serializer.data)
    def get_one(self,request,pk):
        student_obj = Student.objects.get(pk=pk)
        serializer = StudentModelSerializer(instance=student_obj)
        return Response(serializer.data)

from rest_framework.viewsets import GenericViewSet
class Student3GenericViewSet(GenericViewSet):
    serializer_class = StudentModelSerializer
    queryset = Student.objects.all()
    def get_5(self, request):
        student_list = self.get_queryset()[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)
    def get_5_female(self, request):
        student_list = self.get_queryset().filter(sex=False)[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)

from rest_framework.mixins import ListModelMixin, CreateModelMixin
class Student4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ModelViewSet
class Student5ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ReadOnlyModelViewSet
class Student6ReadOnlyModelViewSet(ReadOnlyModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

Only get method

 

Get one

The use of routing class

With the view set, multiple view classes in the view file can be combined into one. However, the routing code becomes complex. We often need to write the corresponding relationship between http request and view method in as view method. In fact, DRF also provides a routing class to simplify the routing code. Of course, this routing class can only be used for view sets.

2.1 basic configuration of routing

url routing configuration

from  django.urls import path,re_path
from collect import views

urlpatterns = [
    #ViewSet
    path('student1/', views.Student1ViewSet.as_view({"get": "get_5"})),
    path('student1/get_5_female/', views.Student1ViewSet.as_view({"get": "get_5_female"})),
    re_path(r'^student1/(?P<pk>\d+)/$', views.Student1ViewSet.as_view({"get": "get_one"})),
    # GenericViewSet
    path('student2/', views.Student3GenericViewSet.as_view({"get": "get_5"})),
    path('student2/get_5_female/', views.Student3GenericViewSet.as_view({"get": "get_5_female"})),
    # GenericViewSet Combined with model class to generate basic API Interface
    path("student3/", views.Student4GenericViewSet.as_view({"get": "list", "post": "create"})),
    # ModelViewSet 5 are provided by default API Interface
    path("student4/", views.Student5ModelViewSet.as_view({"post": "create", "get": "list"})),
    re_path(r"^student4/(?P<pk>\d+)/$",
            views.Student5ModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
    # ReadOnlyModelViewSet
    path("student5/", views.Student6ReadOnlyModelViewSet.as_view({"get": "list"})),
    re_path(r"^student5/(?P<pk>\d+)/$", views.Student6ReadOnlyModelViewSet.as_view({"get": "retrieve"})),
]

# By default, the routing class only gives the basic 5 in the view set API Generate address[ Get one, get multiple, add.delete,Modify data ]
from rest_framework.routers import DefaultRouter
# Instantiate route class
router = DefaultRouter()
# router.register("Access address prefix","View set class","Access alias")
# Register view set classes
router.register("student7", views.Student7ModelViewSet)

print(router.urls)
# Register route list to django In the project
urlpatterns += router.urls

views view file

from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer

from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #Remove all,Parallel slice operation
        queryset = Student.objects.all()[:5]
        #instantiation 
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    def get_5_female(self,request):
        queryset = Student.objects.filter(sex=False)[:5]
        serializer = StudentModelSerializer(instance=queryset, many=True)
        return Response(serializer.data)
    def get_one(self,request,pk):
        student_obj = Student.objects.get(pk=pk)
        serializer = StudentModelSerializer(instance=student_obj)
        return Response(serializer.data)

from rest_framework.viewsets import GenericViewSet
class Student3GenericViewSet(GenericViewSet):
    serializer_class = StudentModelSerializer
    queryset = Student.objects.all()
    def get_5(self, request):
        student_list = self.get_queryset()[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)
    def get_5_female(self, request):
        student_list = self.get_queryset().filter(sex=False)[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)

from rest_framework.mixins import ListModelMixin, CreateModelMixin
class Student4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ModelViewSet
class Student5ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ReadOnlyModelViewSet
class Student6ReadOnlyModelViewSet(ReadOnlyModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.decorators import action
class Student7ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

After restart, view the print content

[
<URLPattern '^student7/$' [name='student-list']>,
<URLPattern '^student7\.(?P<format>[a-z0-9]+)/?$' [name='student-list']>,
<URLPattern '^student7/(?P<pk>[^/.]+)/$' [name='student-detail']>,
<URLPattern '^student7/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$' [name='student-detail']>,
<URLPattern '^$' [name='api-root']>,
<URLPattern '^\.(?P<format>[a-z0-9]+)/?$' [name='api-root']>
]







POSTMAN debugging

Get all

2.2 customize methods and call

Add to views method

from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer

from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #Remove all,Parallel slice operation
        queryset = Student.objects.all()[:5]
        #instantiation 
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    def get_5_female(self,request):
        queryset = Student.objects.filter(sex=False)[:5]
        serializer = StudentModelSerializer(instance=queryset, many=True)
        return Response(serializer.data)
    def get_one(self,request,pk):
        student_obj = Student.objects.get(pk=pk)
        serializer = StudentModelSerializer(instance=student_obj)
        return Response(serializer.data)

from rest_framework.viewsets import GenericViewSet
class Student3GenericViewSet(GenericViewSet):
    serializer_class = StudentModelSerializer
    queryset = Student.objects.all()
    def get_5(self, request):
        student_list = self.get_queryset()[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)
    def get_5_female(self, request):
        student_list = self.get_queryset().filter(sex=False)[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)

from rest_framework.mixins import ListModelMixin, CreateModelMixin
class Student4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ModelViewSet
class Student5ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ReadOnlyModelViewSet
class Student6ReadOnlyModelViewSet(ReadOnlyModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.decorators import action
class Student7ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    # methods Specify what is allowed http Request access to current view method
    # detail  Specifies whether to clamp in the generated routing address pk Value, True For needs
    # @action(methods=['get'], detail=False)
    # def get_4(self, request):
    @action(methods=['get'], detail=True)
    def get_5(self, request, pk):
        serilizer = self.get_serializer(instance=self.get_queryset().get(pk=pk))
        return Response(serilizer.data)

Restart to view printing information

[
<URLPattern '^student7/$' [name='student-list']>,
<URLPattern '^student7\.(?P<format>[a-z0-9]+)/?$' [name='student-list']>,
<URLPattern '^student7/(?P<pk>[^/.]+)/$' [name='student-detail']>,
<URLPattern '^student7/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$' [name='student-detail']>,
<URLPattern '^student7/(?P<pk>[^/.]+)/get_5/$' [name='student-get-5']>,
<URLPattern '^student7/(?P<pk>[^/.]+)/get_5\.(?P<format>[a-z0-9]+)/?$' [name='student-get-5']>,
<URLPattern '^$' [name='api-root']>,
<URLPattern '^\.(?P<format>[a-z0-9]+)/?$' [name='api-root']>]







POSTMAN access custom method

 

2.3 call multiple view planner classes in one view class

url routing configuration

from  django.urls import path,re_path
from collect import views

urlpatterns = [
    #ViewSet
    path('student1/', views.Student1ViewSet.as_view({"get": "get_5"})),
    path('student1/get_5_female/', views.Student1ViewSet.as_view({"get": "get_5_female"})),
    re_path(r'^student1/(?P<pk>\d+)/$', views.Student1ViewSet.as_view({"get": "get_one"})),
    # GenericViewSet
    path('student2/', views.Student3GenericViewSet.as_view({"get": "get_5"})),
    path('student2/get_5_female/', views.Student3GenericViewSet.as_view({"get": "get_5_female"})),
    # GenericViewSet Combined with model class to generate basic API Interface
    path("student3/", views.Student4GenericViewSet.as_view({"get": "list", "post": "create"})),
    # ModelViewSet 5 are provided by default API Interface
    path("student4/", views.Student5ModelViewSet.as_view({"post": "create", "get": "list"})),
    re_path(r"^student4/(?P<pk>\d+)/$",
            views.Student5ModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
    # ReadOnlyModelViewSet
    path("student5/", views.Student6ReadOnlyModelViewSet.as_view({"get": "list"})),
    re_path(r"^student5/(?P<pk>\d+)/$", views.Student6ReadOnlyModelViewSet.as_view({"get": "retrieve"})),
    # Calling multiple serializer in a view class
    path("student8/", views.Student8GenericAPIView.as_view()),
]

# By default, the routing class only gives the basic 5 in the view set API Generate address[ Get one, get multiple, add.delete,Modify data ]
from rest_framework.routers import DefaultRouter
# Instantiate route class
router = DefaultRouter()
# router.register("Access address prefix","View set class","Access alias")
# Register view set classes
router.register("student7", views.Student7ModelViewSet)

print(router.urls)
# Register route list to django In the project
urlpatterns += router.urls

View view configuration

from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer

from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #Remove all,Parallel slice operation
        queryset = Student.objects.all()[:5]
        #instantiation 
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    def get_5_female(self,request):
        queryset = Student.objects.filter(sex=False)[:5]
        serializer = StudentModelSerializer(instance=queryset, many=True)
        return Response(serializer.data)
    def get_one(self,request,pk):
        student_obj = Student.objects.get(pk=pk)
        serializer = StudentModelSerializer(instance=student_obj)
        return Response(serializer.data)

from rest_framework.viewsets import GenericViewSet
class Student3GenericViewSet(GenericViewSet):
    serializer_class = StudentModelSerializer
    queryset = Student.objects.all()
    def get_5(self, request):
        student_list = self.get_queryset()[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)
    def get_5_female(self, request):
        student_list = self.get_queryset().filter(sex=False)[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)

from rest_framework.mixins import ListModelMixin, CreateModelMixin
class Student4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ModelViewSet
class Student5ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ReadOnlyModelViewSet
class Student6ReadOnlyModelViewSet(ReadOnlyModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.decorators import action
class Student7ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    # methods Specify what is allowed http Request access to current view method
    # detail  Specifies whether to clamp in the generated routing address pk Value, True For needs
    # @action(methods=['get'], detail=False)
    # def get_4(self, request):
    @action(methods=['get'], detail=True)
    def get_5(self, request, pk):
        serilizer = self.get_serializer(instance=self.get_queryset().get(pk=pk))
        return Response(serilizer.data)

from rest_framework.generics import GenericAPIView
from collect.serializers import StudentInfoModelSerializer
class Student8GenericAPIView(GenericAPIView):
    queryset = Student.objects.all()

    # GenericAPI We can override this method to call different serializers according to different requirements
    def get_serializer_class(self):
        if self.request.method == "GET":
            # 2 Fields
            return StudentInfoModelSerializer
        return StudentModelSerializer

    def get(self, request):
        """Get all data id and name"""
        student_list = self.get_queryset()
        serializer = self.get_serializer(instance=student_list, many=True)
        # serializer = StudentInfoModelSerializer(instance=student_list, many=True)
        return Response(serializer.data)

    def post(self, request):
        """Add data"""
        data = request.data
        serializer = self.get_serializer(data=data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)

serialization class

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# vim collect/serializers.py

from students.models import Student
from rest_framework import serializers

class StudentModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student
        fields = ["id", "name", "age", "sex"]
        extra_kwargs = {
            "name": {"max_length": 10, "min_length": 4},
            "age": {"max_value": 150, "min_value": 0},
        }
    def validate_name(self, data):
        if data == "root":
            raise serializers.ValidationError("User name cannot be root!")
        return data
    def validate(self, attrs):
        name = attrs.get('name')
        age = attrs.get('age')

        if name == "alex" and age == 22:
            raise serializers.ValidationError("alex The story at 22...")
        return attrs

class StudentInfoModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student
        fields = ["id", "name"]

Visit http://127.0.0.1:8000/collect/student8/

There are only two fields

2.4 using multiple serialization classes within a view set

url configuration

from  django.urls import path,re_path
from collect import views

urlpatterns = [
    #ViewSet
    path('student1/', views.Student1ViewSet.as_view({"get": "get_5"})),
    path('student1/get_5_female/', views.Student1ViewSet.as_view({"get": "get_5_female"})),
    re_path(r'^student1/(?P<pk>\d+)/$', views.Student1ViewSet.as_view({"get": "get_one"})),
    # GenericViewSet
    path('student2/', views.Student3GenericViewSet.as_view({"get": "get_5"})),
    path('student2/get_5_female/', views.Student3GenericViewSet.as_view({"get": "get_5_female"})),
    # GenericViewSet Combined with model class to generate basic API Interface
    path("student3/", views.Student4GenericViewSet.as_view({"get": "list", "post": "create"})),
    # ModelViewSet 5 are provided by default API Interface
    path("student4/", views.Student5ModelViewSet.as_view({"post": "create", "get": "list"})),
    re_path(r"^student4/(?P<pk>\d+)/$",
            views.Student5ModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
    # ReadOnlyModelViewSet
    path("student5/", views.Student6ReadOnlyModelViewSet.as_view({"get": "list"})),
    re_path(r"^student5/(?P<pk>\d+)/$", views.Student6ReadOnlyModelViewSet.as_view({"get": "retrieve"})),
    # Calling multiple serializer in a view class
    path("student8/", views.Student8GenericAPIView.as_view()),
    # A view concentrates on calling multiple serializer.
    path("student9/", views.Student9ModelViewSet.as_view({"get": "list"})),
    re_path(r"^student9/(?P<pk>\d+)/$", views.Student9ModelViewSet.as_view({"get": "retrieve"})),
]

# By default, the routing class only gives the basic 5 in the view set API Generate address[ Get one, get multiple, add.delete,Modify data ]
from rest_framework.routers import DefaultRouter
# Instantiate route class
router = DefaultRouter()
# router.register("Access address prefix","View set class","Access alias")
# Register view set classes
router.register("student7", views.Student7ModelViewSet)

print(router.urls)
# Register route list to django In the project
urlpatterns += router.urls

views configuration

requirement:

  • List data list, return 2 fields,
  • Detailed data retrieve, return all fields
from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer

from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #Remove all,Parallel slice operation
        queryset = Student.objects.all()[:5]
        #instantiation 
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    def get_5_female(self,request):
        queryset = Student.objects.filter(sex=False)[:5]
        serializer = StudentModelSerializer(instance=queryset, many=True)
        return Response(serializer.data)
    def get_one(self,request,pk):
        student_obj = Student.objects.get(pk=pk)
        serializer = StudentModelSerializer(instance=student_obj)
        return Response(serializer.data)

from rest_framework.viewsets import GenericViewSet
class Student3GenericViewSet(GenericViewSet):
    serializer_class = StudentModelSerializer
    queryset = Student.objects.all()
    def get_5(self, request):
        student_list = self.get_queryset()[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)
    def get_5_female(self, request):
        student_list = self.get_queryset().filter(sex=False)[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)

from rest_framework.mixins import ListModelMixin, CreateModelMixin
class Student4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ModelViewSet
class Student5ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ReadOnlyModelViewSet
class Student6ReadOnlyModelViewSet(ReadOnlyModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.decorators import action
class Student7ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    # methods Specify what is allowed http Request access to current view method
    # detail  Specifies whether to clamp in the generated routing address pk Value, True For needs
    # @action(methods=['get'], detail=False)
    # def get_4(self, request):
    @action(methods=['get'], detail=True)
    def get_5(self, request, pk):
        serilizer = self.get_serializer(instance=self.get_queryset().get(pk=pk))
        return Response(serilizer.data)

from rest_framework.generics import GenericAPIView
from collect.serializers import StudentInfoModelSerializer
class Student8GenericAPIView(GenericAPIView):
    queryset = Student.objects.all()

    # GenericAPI We can override this method to call different serializers according to different requirements
    def get_serializer_class(self):
        if self.request.method == "GET":
            # 2 Fields
            return StudentInfoModelSerializer
        return StudentModelSerializer

    def get(self, request):
        """Get all data id and name"""
        student_list = self.get_queryset()

        serializer = self.get_serializer(instance=student_list, many=True)
        # serializer = StudentInfoModelSerializer(instance=student_list, many=True)

        return Response(serializer.data)

    def post(self, request):
        """Add data"""
        data = request.data
        serializer = self.get_serializer(data=data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)

class Student9ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    def get_serializer_class(self):
        # The view method name requested by the client  self.action
        print(self.action)
        if self.action == "list":
            return StudentInfoModelSerializer
        return StudentModelSerializer

get gets all but two fields

The printed result is list

Output single information, output 4 fields

Method name

III. extended functions of DRF

Create a new app app

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# python3 manage.py startapp opt

register

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'students.apps.StudentsConfig',
    'ser.apps.SerConfig',
    'req.apps.ReqConfig',
    'collect.apps.CollectConfig',
    'opt.apps.OptConfig',
]

Configure fonts

LANGUAGE_CODE = 'zh-hans'

Add routing distribution

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('student/',include("students.urls")),
    path('ser/',include("ser.urls")),
    path('req/', include("req.urls")),
    path('collect/', include("collect.urls")),
    path('opt/', include("opt.urls")),
]

3.1 user control

Create route file

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# vim opt/urls.py

from django.urls import path
from opt import views

urlpatterns = [
    path('auth1/', views.Demo1APIView.as_view()),
    path('auth2/', views.Demo2APIView.as_view()),
]

views file

from django.shortcuts import render
# Create your views here.
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAdminUser

#Authentication and authority identification of users
class Demo1APIView(APIView):
    #Only users after login are allowed to access
    permission_classes = [IsAuthenticated]
    def get(self, request):
        #Personal Center
        return Response("Personal Center")

class Demo2APIView(APIView):
    #Allow administrator access only
    permission_classes = [IsAdminUser]
    def get(self, request):
        #Personal center 2
        return Response("Personal center 2")

Visit http://127.0.0.1:8000/opt/auth1/

Create an admin user to manage

 

Sign in http://127.0.0.1:8000/admin/login/?next=/admin/ 

After logging in, view http://127.0.0.1:8000/opt/auth1/ Sum http://127.0.0.1:8000/opt/auth2/

Create an alex user

Log in with alex and cancel personnel status

Then auth1 can access normally, but access http://127.0.0.1:8000/opt/auth2/

Must be a super administrator user to see

View the seeeion of data

 mysql> select * from django_session;

+----------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+
| session_key                      | session_data                                                                                                                                                                                                                                                 | expire_date                |
+----------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+
| fn55zqveedvfjckalewwusqny7iadhun | MWM5NDBiNmI0ZDZlYTFmZmM4MjE4YTkyODcyMWNmNTQ4NjJkNDJkNTp7Il9hdXRoX3VzZXJfaWQiOiIyIiwiX2F1dGhfdXNlcl9iYWNrZW5kIjoiZGphbmdvLmNvbnRyaWIuYXV0aC5iYWNrZW5kcy5Nb2RlbEJhY2tlbmQiLCJfYXV0aF91c2VyX2hhc2giOiIwMTY2ZDUxMTFhYzU2ZTBjMWRkZDU5ZmM3MmE5ZmI1ZjcyYWY4NmMxIn0= | 2020-05-05 07:27:10.353593 |
+----------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+

3.2 permission control

Permission control can restrict users' access to views and specific data objects.

  • Before executing the dispatch() method of a view, the view access permission will be determined first

  • When getting specific objects through get_object(), the access rights of model objects will be judged

Built in permissions:

  • AllowAny allows all users

  • IsAuthenticated authenticated users only

  • IsAdminUser administrator only

  • IsAuthenticatedOrReadOnly users who have logged in for authentication can add, delete, and modify data. Users who have not logged in for authentication can only view data.

You can set the default permission management class globally in the configuration file, such as:

REST_FRAMEWORK = {
    ....
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    )
}

If not specified, the default configuration is as follows

'DEFAULT_PERMISSION_CLASSES': (
   'rest_framework.permissions.AllowAny',

Custom permissions

url configuration

from django.urls import path,re_path
from opt import views

urlpatterns = [
    path('auth1/', views.Demo1APIView.as_view()),
    path('auth2/', views.Demo2APIView.as_view()),
    # Custom permissions
    path('auth3/', views.Demo3APIView.as_view()),
]

views configuration

from django.shortcuts import render
# Create your views here.
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAdminUser

#Authentication and authority identification of users
class Demo1APIView(APIView):
    #Only users after login are allowed to access
    permission_classes = [IsAuthenticated]
    def get(self, request):
        #Personal Center
        return Response("Personal Center")

class Demo2APIView(APIView):
    #Allow administrator access only
    permission_classes = [IsAdminUser]
    def get(self, request):
        #Personal center 2
        return Response("Personal center 2")

# Custom permissions
from rest_framework.permissions import BasePermission

class MyPermission(BasePermission):
    def has_permission(self, request, view):
        """
        //Right judgment for access view
        :param request: Of this operation http Request object
        :param view:  View object corresponding to this access route
        :return:
        """
        if request.user.username == "xiaoming":
            return True
        return False

class Demo3APIView(APIView):
    permission_classes = [MyPermission]

    def get(self, request):
        """Personal center 3"""
        return Response("Personal center 3")

Creating a xiaoming user

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# python3 manage.py createsuperuser

Using root login to access auth3

Log in and access with ixaoming user

3.3 Throttling

The frequency of interface access can be limited to reduce server pressure.

Generally used for paying purchase times, voting and other scenarios

In the configuration file, you can use default? Throttle? Classes and default? Throttle? Rates for global configuration

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# vim drf_demo/settings.py 

REST_FRAMEWORK = {
    # Current limiting
    'DEFAULT_THROTTLE_CLASSES': (  # Set global
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle'
    ),
    'DEFAULT_THROTTLE_RATES': {
        'anon': '3/hour',
        'user': '3/minute',
    }
}

Default? Round? Rates you can use second, minute, hour, or day to indicate a period.

URL file

from django.urls import path,re_path
from opt import views

urlpatterns = [
    path('auth1/', views.Demo1APIView.as_view()),
    path('auth2/', views.Demo2APIView.as_view()),
    # Custom permissions
    path('auth3/', views.Demo3APIView.as_view()),
    # Current limiting
    path('auth4/', views.Demo4APIView.as_view()),
]

views view file

from django.shortcuts import render
# Create your views here.
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAdminUser

#Authentication and authority identification of users
class Demo1APIView(APIView):
    #Only users after login are allowed to access
    permission_classes = [IsAuthenticated]
    def get(self, request):
        #Personal Center
        return Response("Personal Center")

class Demo2APIView(APIView):
    #Allow administrator access only
    permission_classes = [IsAdminUser]
    def get(self, request):
        #Personal center 2
        return Response("Personal center 2")

# Custom permissions
from rest_framework.permissions import BasePermission

class MyPermission(BasePermission):
    def has_permission(self, request, view):
        """
        //For access view permission judgment, you must use xiaoming user
        :param request: Of this operation http Request object
        :param view:  View object corresponding to this access route
        :return:
        """
        if request.user.username == "xiaoming":
            return True
        return False

class Demo3APIView(APIView):
    permission_classes = [MyPermission]

    def get(self, request):
        """Personal center 3"""
        return Response("Personal center 3")

# Current limiting
from rest_framework.throttling import UserRateThrottle, AnonRateThrottle
class Demo4APIView(APIView):
    throttle_classes = [UserRateThrottle, AnonRateThrottle]  # After global configuration, there is no need to specify
    def get(self, request):
        """Voting page"""
        return Response("Voting page")

Visit auth4

When more than 3 times

 

Logout user, the number of anonymous users exceeded

 

3.4 Filtering

For list data that may need to be filtered according to fields, we can enhance support by adding Django filter extension.

Install Django filter

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# pip3 install django-filter

register

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    
    'rest_framework',
    'django_filters',  # App registration is required,
    
    'students.apps.StudentsConfig',
    'ser.apps.SerConfig',
    'req.apps.ReqConfig',
    'collect.apps.CollectConfig',
    'opt.apps.OptConfig',
]

Configure url routing

from django.urls import path,re_path
from opt import views

urlpatterns = [
    path('auth1/', views.Demo1APIView.as_view()),
    path('auth2/', views.Demo2APIView.as_view()),
    # Custom permissions
    path('auth3/', views.Demo3APIView.as_view()),
    # Current limiting
    path('auth4/', views.Demo4APIView.as_view()),
    # filter
    path('data5/', views.Demo5APIView.as_view()),
]

views view

from django.shortcuts import render
# Create your views here.
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAdminUser

#Authentication and authority identification of users
class Demo1APIView(APIView):
    #Only users after login are allowed to access
    permission_classes = [IsAuthenticated]
    def get(self, request):
        #Personal Center
        return Response("Personal Center")

class Demo2APIView(APIView):
    #Allow administrator access only
    permission_classes = [IsAdminUser]
    def get(self, request):
        #Personal center 2
        return Response("Personal center 2")

# Custom permissions
from rest_framework.permissions import BasePermission

class MyPermission(BasePermission):
    def has_permission(self, request, view):
        """
        //For access view permission judgment, you must use xiaoming user
        :param request: Of this operation http Request object
        :param view:  View object corresponding to this access route
        :return:
        """
        if request.user.username == "xiaoming":
            return True
        return False

class Demo3APIView(APIView):
    permission_classes = [MyPermission]

    def get(self, request):
        """Personal center 3"""
        return Response("Personal center 3")

# Current limiting
from rest_framework.throttling import UserRateThrottle, AnonRateThrottle
class Demo4APIView(APIView):
    throttle_classes = [UserRateThrottle, AnonRateThrottle]  # After global configuration, there is no need to specify
    def get(self, request):
        """Voting page"""
        return Response("Voting page")

# filter
from rest_framework.generics import GenericAPIView, ListAPIView
from students.models import Student
from opt.serializers import StudentModelSerializer
from django_filters.rest_framework import DjangoFilterBackend
# 'django_filters.rest_framework.DjangoFilterBackend'
class Demo5APIView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    filter_backends = [DjangoFilterBackend]  # After global configuration, there is no need to specify.
    filter_fields = ['age', "id"]  # Declare filter fields

Copy a serialization class

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# cp collect/serializers.py     opt/

setting settings

REST_FRAMEWORK = {
    # Current limiting
    'DEFAULT_THROTTLE_CLASSES': (  # Set global
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle'
    ),
    'DEFAULT_THROTTLE_RATES': {
        'anon': '3/hour',
        'user': '3/minute',
    }
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}

Visit http://127.0.0.1:8000/opt/data5/

 

Click filter

 

Submission

3.5 Ordering

For list data, REST framework provides OrderingFilter filter to help us quickly indicate that the data is sorted according to the specified fields.

usage method:

Set filter_backends in the class view, and use the rest_framework.filters.ordering filter filter. The REST framework will check whether the order parameter is included in the query string parameter of the request. If the order parameter is included, the data set will be sorted according to the order field specified by the order parameter.

The optional field values of the ordering parameters that can be passed by the front end need to be specified in the ordering fields.

Routing configuration

from django.urls import path,re_path
from opt import views

urlpatterns = [
    path('auth1/', views.Demo1APIView.as_view()),
    path('auth2/', views.Demo2APIView.as_view()),
    # Custom permissions
    path('auth3/', views.Demo3APIView.as_view()),
    # Current limiting
    path('auth4/', views.Demo4APIView.as_view()),
    # filter
    path('data5/', views.Demo5APIView.as_view()),
    # sort
    path('data6/', views.Demo6APIView.as_view()),
]

views view configuration

from django.shortcuts import render
# Create your views here.
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAdminUser

#Authentication and authority identification of users
class Demo1APIView(APIView):
    #Only users after login are allowed to access
    permission_classes = [IsAuthenticated]
    def get(self, request):
        #Personal Center
        return Response("Personal Center")

class Demo2APIView(APIView):
    #Allow administrator access only
    permission_classes = [IsAdminUser]
    def get(self, request):
        #Personal center 2
        return Response("Personal center 2")

# Custom permissions
from rest_framework.permissions import BasePermission

class MyPermission(BasePermission):
    def has_permission(self, request, view):
        """
        //For access view permission judgment, you must use xiaoming user
        :param request: Of this operation http Request object
        :param view:  View object corresponding to this access route
        :return:
        """
        if request.user.username == "xiaoming":
            return True
        return False

class Demo3APIView(APIView):
    permission_classes = [MyPermission]

    def get(self, request):
        """Personal center 3"""
        return Response("Personal center 3")

# Current limiting
from rest_framework.throttling import UserRateThrottle, AnonRateThrottle
class Demo4APIView(APIView):
    throttle_classes = [UserRateThrottle, AnonRateThrottle]  # After global configuration, there is no need to specify
    def get(self, request):
        """Voting page"""
        return Response("Voting page")

# filter
from rest_framework.generics import GenericAPIView, ListAPIView
from students.models import Student
from opt.serializers import StudentModelSerializer
from django_filters.rest_framework import DjangoFilterBackend
# 'django_filters.rest_framework.DjangoFilterBackend'
class Demo5APIView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    filter_backends = [DjangoFilterBackend]  # After global configuration, there is no need to specify.
    filter_fields = ['age', "id"]  # Declare filter fields

# sort
from rest_framework.filters import OrderingFilter


class Demo6APIView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    filter_backends = [DjangoFilterBackend, OrderingFilter]  # Local configuration will override global configuration
    filter_fields = ['id', "sex"]
    ordering_fields = ['id', "age"]

Visit http://127.0.0.1:8000/opt/data6/

Click filter

 

3.6 Pagination

REST framework provides paging support.

We can set the global paging mode in the configuration file, such as:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS':  'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 100  # Number of pages
}

You can also add different paging behaviors to the view by customizing the paging class. It is indicated in the view by the Pagination ﹣ clas attribute.

urls.py under opt
from django.urls import path,re_path
from opt import views

urlpatterns = [
    path('auth1/', views.Demo1APIView.as_view()),
    path('auth2/', views.Demo2APIView.as_view()),
    # Custom permissions
    path('auth3/', views.Demo3APIView.as_view()),
    # Current limiting
    path('auth4/', views.Demo4APIView.as_view()),
    # filter
    path('data5/', views.Demo5APIView.as_view()),
    # sort
    path('data6/', views.Demo6APIView.as_view()),
    # paging
    path('data7/', views.Demo7APIView.as_view()),
]

views view file

from django.shortcuts import render
# Create your views here.
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAdminUser

#Authentication and authority identification of users
class Demo1APIView(APIView):
    #Only users after login are allowed to access
    permission_classes = [IsAuthenticated]
    def get(self, request):
        #Personal Center
        return Response("Personal Center")

class Demo2APIView(APIView):
    #Allow administrator access only
    permission_classes = [IsAdminUser]
    def get(self, request):
        #Personal center 2
        return Response("Personal center 2")

# Custom permissions
from rest_framework.permissions import BasePermission

class MyPermission(BasePermission):
    def has_permission(self, request, view):
        """
        //For access view permission judgment, you must use xiaoming user
        :param request: Of this operation http Request object
        :param view:  View object corresponding to this access route
        :return:
        """
        if request.user.username == "xiaoming":
            return True
        return False

class Demo3APIView(APIView):
    permission_classes = [MyPermission]

    def get(self, request):
        """Personal center 3"""
        return Response("Personal center 3")

# Current limiting
from rest_framework.throttling import UserRateThrottle, AnonRateThrottle
class Demo4APIView(APIView):
    throttle_classes = [UserRateThrottle, AnonRateThrottle]  # After global configuration, there is no need to specify
    def get(self, request):
        """Voting page"""
        return Response("Voting page")

# filter
from rest_framework.generics import GenericAPIView, ListAPIView
from students.models import Student
from opt.serializers import StudentModelSerializer
from django_filters.rest_framework import DjangoFilterBackend
# 'django_filters.rest_framework.DjangoFilterBackend'
class Demo5APIView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    filter_backends = [DjangoFilterBackend]  # After global configuration, there is no need to specify.
    filter_fields = ['age', "id"]  # Declare filter fields

# sort
from rest_framework.filters import OrderingFilter


class Demo6APIView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    filter_backends = [DjangoFilterBackend, OrderingFilter]  # Local configuration will override global configuration
    filter_fields = ['id', "sex"]
    ordering_fields = ['id', "age"]

#paging
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination

"""1. Custom pager, customize the configuration of paging"""
"""
# Page PageNumberPagination
//Front end access form: get http: / / 127.0.0.1:8000 / opt / data7 /? Page = 4

page=1   limit 0,10
page=2   limit 10,20

# Offset pagination LimitOffsetPagination
//Front end access form: get http://127.0.0.1:8000 / opt / data7 /? Start = 4 & size = 3

start=0  limit 0,10
start=10 limit 10,10
start=20 limit 20,10
"""


class StandardPageNumberPagination(PageNumberPagination):
    """Paging related configuration"""
    page_query_param = "page"          # Set page number key name
    page_size = 3                      # Set the number of data displayed per page
    page_size_query_param = "size"     # Set the keyword name for the specified page size
    max_page_size = 5                  # Set maximum display per page


class StandardLimitOffsetPagination(LimitOffsetPagination):
    default_limit = 2                  # Default limit, default value and PAGE_SIZE Consistent settings
    limit_query_param = "size"         # limit Parameter name
    offset_query_param = "start"       # offset Parameter name
    max_limit = 5                      # Maximum limit limit


class Demo7APIView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    # paging
    # Page pagination class
    pagination_class = StandardPageNumberPagination
    # Offset paging class
    # pagination_class = StandardLimitOffsetPagination

Visit http://127.0.0.1:8000/opt/data7/

 

Visit http://127.0.0.1:8000/opt/data7/?page=1&size=8 , that is, each page displays 8 data

But only five will be displayed, which is the maximum display of five in the code setting. When eight are displayed in the setting, it will not take effect, only five will be displayed

reference resources: https://www.cnblogs.com/Michael--chen/p/11222143.html Education for old boys: https://www.oldboyedu.com/ 

Posted by NorthWestSimulations on Tue, 21 Apr 2020 22:30:51 -0700