首页 > 其他分享 >基于GenericAPIView+5个视图扩展类接口

基于GenericAPIView+5个视图扩展类接口

时间:2023-02-05 16:44:16浏览次数:39  
标签:GenericAPIView obj get self request 接口 视图 kwargs return

APIView与原生区别

APIView属于drf视图基类

#drf中APIView与django原生的View区别 
1.继承这个类后,视图方法中的request变为了drf的request而不是原生django的request
2.继承了APIView的类,返回的对象应该使用drf里面的Response对象,
3.任何的异常都会捕获到,并处理成合适的响应信息
4.然后在执行类方法前,会对请求进行3大认证,身份认证,权限检查,流量控制
     

基于GenericAPIView+ModelSerializer写5个接口

视图类

from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from .serializer import UserSerializer
from .models import User, UserInfo

class UserView(GenericAPIView):
    queryset = User.objects.all()
    # 需要序列化或反序列化的全部数据
    serializer_class = UserSerializer
    # 需要使用的序列化类

    def get(self, request, **kwargs):
        if kwargs:
          # 判断路由是否有额外参数eg:pk
          # 有就是获取单个对象
            obj = self.get_object()
            # 独有方法,通过路由传入获取单个对象
            ser = self.get_serializer(instance=obj)
            # get_serializer获取要使用的序列化类,
            # 还有一个get_serializer_class方法 可以重新 
            return Response(ser.data)
        else:
            objs = self.get_queryset()
            # 独有方法,获取数据全部对象
            # 也可以重写该方法 达到某种目的
            ser = self.get_serializer(instance=objs, many=True)
            return Response(ser.data)

    def post(self, request):
        ser = self.get_serializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'msg': '添加成功', 'result': ser.data})
        else:
            return Response({'msg': ser.errors})

    def put(self, request, pk):
        obj = self.get_object()
        ser = self.get_serializer(instance=obj, data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'msg': '修改成功', 'result': ser.data})
        else:
            return Response({'msg': ser.errors})

    def delete(self, request, pk):
        User_obj = self.get_object()
        UserInfo.objects.filter(pk=User_obj.userinfo_id).delete()
        User_obj.delete()
        return Response({'msg': '删除成功'})
      
      
# GenericAPIView方法:
				1.get_queryset()
        2.get_object()
        3.get_serializer()

序列化类

from rest_framework import serializers
from .models import User, UserInfo


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        # 关联表设置
        fields = ['id', 'name', 'phone', 'info', 'addr', 'word']
        # 需要用的字段注册

    info = serializers.DictField(write_only=True)
    # 接收前端传入的字典格式数据

    addr = serializers.SerializerMethodField(read_only=True)
    # 不属于关联表的字段 需要自己写

    def get_addr(self, obj):
        return {'addr': obj.userinfo.addr}

    word = serializers.SerializerMethodField(read_only=True)
    # 不属于关联表的字段 需要自己写

    def get_word(self, obj):
        return {'work': obj.userinfo.word}

    def create(self, validated_data):
        info = validated_data.get('info')
        info_obj = UserInfo.objects.create(addr=info.get('addr'), word=info.get('word'))
        obj = User.objects.create(name=validated_data.get('name'),
                                  phone=validated_data.get('phone'),
                                  userinfo_id=info_obj.pk)
        return obj
      
     # 重写保存方法

进化-基于5个视图扩展类

视图类

导入封装好的5个视图扩展类 并继承 然后使用其中的方法


from .serializer import UserSerializer
from rest_framework.generics import GenericAPIView
from .models import User, UserInfo
from rest_framework.mixins import CreateModelMixin, RetrieveModelMixin, ListModelMixin, UpdateModelMixin, DestroyModelMixin

'''
5个视图扩展类:
CreateModelMixin : 创建数据  --create方法
                 (原理还是调用了序列化类中的create方法)
RetrieveModelMixin : 查询单条数据 --retrieve方法    
ListModelMixin:  查询所有用户数据  -- list方法
UpdateModelMixin: 修改单条数据  -- update方法
                 (原理还是调用了序列化类中的update方法)
DestroyModelMixin: 删除单条数据  --destroy方法
具体用法如下:这个必须搭配GenericAPIView一起使用
'''



class UserView(GenericAPIView, CreateModelMixin, RetrieveModelMixin, ListModelMixin, UpdateModelMixin,DestroyModelMixin):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    def get(self, request, *args, **kwargs):
        if kwargs:
            return self.retrieve(request, *args, **kwargs)
        else:
            return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

序列化类

from rest_framework import serializers
from .models import User, UserInfo


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'name', 'phone', 'info', 'addr', 'word']

    info = serializers.DictField(write_only=True)

    addr = serializers.SerializerMethodField(read_only=True)

    def get_addr(self, obj):
        return {'addr': obj.userinfo.addr}

    word = serializers.SerializerMethodField(read_only=True)

    def get_word(self, obj):
        return {'work': obj.userinfo.word}

    def create(self, validated_data):
        info = validated_data.get('info')
        info_obj = UserInfo.objects.create(addr=info.get('addr'), word=info.get('word'))
        obj = User.objects.create(name=validated_data.get('name'),
                                  phone=validated_data.get('phone'),
                                  userinfo_id=info_obj.pk)
        return obj
    # 因为涉及了两张表 所以需要重写创建方法

再次封装视图基类和GenericAPIView

from rest_framework.generics import ListAPIView, CreateAPIView, RetrieveAPIView, UpdateAPIView, DestroyAPIView

# drf更加方法的为你把GenericAPIView的功能和视图基类的功能合并了
ListAPIView, CreateAPIView, RetrieveAPIView, UpdateAPIView, DestroyAPIView

class UserView(ListAPIView, CreateAPIView, RetrieveAPIView, UpdateAPIView, DestroyAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    
# 直接继承这些类就可以完成增删改查

分析:
class ListAPIView(mixins.ListModelMixin,
                  GenericAPIView):
    """
    Concrete view for listing a queryset.
    """
    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)
      
# 其实你导入的ListAPIView并继承了这个类,那就相当于你有了get方法

# 一个视图类实现 查所有和查单个 其实就是区分url有没有传pk这个属性

class UserView(ListAPIView, CreateAPIView, RetrieveAPIView, UpdateAPIView, DestroyAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    def get(self, request, *args, **kwargs):
      # 我们可以自身写一个get区分一下,然后在执行是 查询单个的类 还是查询所有的类
        if kwargs:
            return RetrieveAPIView.get(self, request, *args, **kwargs)
        else:
            return ListAPIView.get(self, request, *args, **kwargs)
    
    
# 以上代码也实现了基本的5个接口功能

标签:GenericAPIView,obj,get,self,request,接口,视图,kwargs,return
From: https://www.cnblogs.com/moongodnnn/p/17093558.html

相关文章