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
posted @ 2020-07-08 21:17  群青-Xi  阅读(113)  评论(0编辑  收藏  举报