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