zoukankan      html  css  js  c++  java
  • rest_framework视图

    rest_framework视图:一步步精简代码

    使用APIView实现(返回时使用自己封装的response)

    # models.py
    from django.db import models
    class Student(models.Model):
        sid = models.AutoField(primary_key=True)
        name = models.CharField(max_length=24)
        age = models.IntegerField()
        gender = models.CharField(max_length=1)
    
    # urls.py
    path('studentAPI/', views.StudentsAPIView.as_view()),
    re_path(r'studentAPI/(?P<pk>d+)/', views.StudentAPIView.as_view()),
    
    # modelserializer.py
    from rest_framework import serializers
    from drf_day03.models import Student
    class StudentModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = Student
            fields = '__all__'
            read_only_fields = ('sid', )
    
            
    # Respon封装类 utils.py
    from rest_framework.response import Response
    class MyResponse(Response):
        def __init__(self, info_status, message, data=''):
            self.back_dic = {
                'status': info_status, # 请求返回的状态码
                'message': message, # 提示信息
                'request': data # 返回的数据
            }
            super().__init__(data=self.back_dic)
            
    # views.py
    from rest_framework.views import APIView
    from drf_day03.modelserializer import StudentModelSerializer
    from drf_day03.models import Student
    from drf_day03.utils import MyResponse
    
    """使用APIView实现5个接口, 使用自己封装的Response方法返回数据"""
    class StudentsAPIView(APIView):
        def get(self, request):
            instance_list = Student.objects.all()
            stuModelSerializer = StudentModelSerializer(instance=instance_list, many=True)
            return MyResponse(100, 'ok', stuModelSerializer.data)
    
        def post(self, request):
            stuModelSerializer = StudentModelSerializer(data=request.data)
            if stuModelSerializer.is_valid():
                stuModelSerializer.save()
                return MyResponse(101, '创建成功', stuModelSerializer.data)
            else:
                return MyResponse(103, '创建失败', stuModelSerializer.errors)
    
    
    class StudentAPIView(APIView):
        def get(self, request, pk):
            instance = Student.objects.filter(pk=pk).first()
            if instance:
                stuModelSerializer = StudentModelSerializer(instance=instance)
                return MyResponse(100, 'ok', stuModelSerializer.data)
            else:
                return MyResponse(104, '数据不存在')
    
        def put(self, request, pk):
            instance = Student.objects.filter(pk=pk).first()
            if instance:
                stuModelSerializer = StudentModelSerializer(instance=instance, data=request.data)
                if stuModelSerializer.is_valid():
                    stuModelSerializer.save()
                    return MyResponse(100, '修改成功', stuModelSerializer.data)
                else:
                    return MyResponse(101, '修改失败', stuModelSerializer.errors)
            else:
                return MyResponse(104, '数据不存在')
    
        def delete(self, request, pk):
            Student.objects.filter(pk=pk).delete()
            return MyResponse(100, '删除成功')
    

    使用GenericAPIView(需要两个参数:queryset、serializer_class)

    # urls.py
    path('studentGenericAPI/', views.StudentsGenericAPIView.as_view()),
    re_path(r'studentGenericAPI/(?P<pk>d+)/', views.StudentGenericAPIView.as_view()),
    
    # views.py
    from rest_framework.generics import GenericAPIView
    from drf_day03.modelserializer import StudentModelSerializer
    from drf_day03.models import Student
    from drf_day03.utils import MyResponse
    class StudentsGenericAPIView(GenericAPIView):
        queryset = Student.objects
        serializer_class = StudentModelSerializer
    
        def get(self, request):
            instance_list = self.get_queryset()
            stuModelSerializer = self.get_serializer(instance=instance_list, many=True)
            return MyResponse(100, 'ok', stuModelSerializer.data)
    
        def post(self, request):
            stuModelSerializer = self.get_serializer(data=request.data)
            if stuModelSerializer.is_valid():
                stuModelSerializer.save()
                return MyResponse(101, '创建成功', stuModelSerializer.data)
            else:
                return MyResponse(103, '创建失败', stuModelSerializer.errors)
    
    
    class StudentGenericAPIView(GenericAPIView):
        queryset = Student.objects
        serializer_class = StudentModelSerializer
        def get(self, request, pk):
            instance = self.get_object()
            if instance:
                stuModelSerializer = self.get_serializer(instance=instance)
                return MyResponse(100, 'ok', stuModelSerializer.data)
            else:
                return MyResponse(104, '数据不存在')
    
        def put(self, request, pk):
            instance = self.get_object()
            if instance:
                stuModelSerializer = self.get_serializer(instance=instance, data=request.data)
                if stuModelSerializer.is_valid():
                    stuModelSerializer.save()
                    return MyResponse(100, '修改成功', stuModelSerializer.data)
                else:
                    return MyResponse(101, '修改失败', stuModelSerializer.errors)
            else:
                return MyResponse(104, '数据不存在')
    
        def delete(self, request, pk):
            Student.objects.filter(pk=pk).delete()
            return MyResponse(100, '删除成功')
    

    使用5个视图扩展类实现(继承GenericAPIView以及一个或多个视图扩展类)

    • ListModelMixin:查多条数据self.list(request)
    • CreateModelMixin:创建一条数据self.create(request)
    • UpdateModelMixin:修改一条数据self.update(request, pk)
    • RetrieveModelMixin:查询一条数据self.retrieve(request, pk)
    • DestroyModelMixin:删除一条数据self.destroy(request, pk)
    # urls.py
    path('studentGenericAPI2/', views.StudentsGenericAPIView2.as_view()),
    re_path(r'studentGenericAPI2/(?P<pk>d+)/', views.StudentGenericAPIView2.as_view()),
    
    # views.py
    from rest_framework.mixins import ListModelMixin, CreateModelMixin, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin
    class StudentsGenericAPIView2(GenericAPIView, ListModelMixin, CreateModelMixin):
        queryset = Student.objects
        serializer_class = StudentModelSerializer
    
        def get(self, request):
            return self.list(request)
    
        def post(self, request):
            return self.create(request)
    
    
    class StudentGenericAPIView2(GenericAPIView, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin):
        queryset = Student.objects
        serializer_class = StudentModelSerializer
        def get(self, request, pk):
            return self.retrieve(request, pk)
    
        def put(self, request, pk):
            return self.update(request, pk)
    
        def delete(self, request, pk):
            return self.destroy(request, pk)
    

    使用ModelViewSet实现CURD(继承GenericViewSet以及5个视图扩展类,路由的as_view()中必须指定actions)

    • GenericViewSet又继承了ViewSetMixin和GenericAPIView,其核心功能就在ViewSetMixin重写的as_view方法中

      def view(request, *args, **kwargs):
          self = cls(**initkwargs)
          self.action_map = actions # {'get': 'list', 'post': 'create'}
          for method, action in actions.items():
              # method就是请求方式(get),action就是对应的方法(list)
              handler = getattr(self, action) # 通过反射获取请求方式对应方法的内存地址
              setattr(self, method, handler) # 对象.get = list、对象.post=create
              # for循环执行完毕后对象.get就指向了list的内存地址,对象.post就指向了create的内存地址
              
      # 我们可以通过继承ViewSetMixin的视图类来实现多个接口指向同一个类视图执行不同的方法
      
    # urls.py
    path('studentModelViewSet/', views.StudentsModelViewSet.as_view(
        actions={'get': 'list', 'post': 'create'})),
    re_path(r'studentModelViewSet/(?P<pk>d+)/', views.StudentsModelViewSet.as_view(
        actions={'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
    
    # views.py
    from rest_framework.viewsets import ModelViewSet
    class StudentsModelViewSet(ModelViewSet):
        queryset = Student.objects
        serializer_class = StudentModelSerializer
    
  • 相关阅读:
    map映射的用法
    相似的字串(hash+二分)
    进制 /字符串 hash
    CF#632 C.Eugene and an array
    2020牛客寒假算法基础集训营6 H-云
    Educational Codeforces Round 80 (Div. 2)
    Codeforces Round #601 (Div. 2)补题
    luogu-单调队列/单调栈专题
    Comet OJ
    Comet OJ
  • 原文地址:https://www.cnblogs.com/guanxiying/p/13269252.html
Copyright © 2011-2022 走看看