Django REST framework 视图的演变与使用

Django REST framework 视图的演变与使用

在这里插入图片描述

标题版本一(基于类视图APIView类)

views.py:
APIView是继承的Django View视图的

from .serializers import UserSerializers    #导入当前目录配置好的序列化器                 
from .models import User                    #导入数据库
from rest_framework.views import APIView    #导入APIView 
from rest_framework.response import Response  #该模块返回json数据
from rest_framework import status           #内置状态码模块

class UserAPIView(APIView):          #查看所有及添加数据视图
    def get(self,request):    
        users = User.objects.all()          #获取数据库里所有数据
        ser = UserSerializers(instance=users,many=True) #进行序列化操作,指定更多集合对象
        return Response(ser.data,status=200)#返回成功数据

    def post(self,request):          #添加数据
        ser = UserSerializers(data=request.data)#接收前台传输数据
        if ser.is_valid():                  #判断书否合法raise_exception=True加次参数表示不合法抛出异常,默认false
            ser.save()                      #保存
            return Response(ser.data,status=200)
        return Response(ser.errors)         #返回错误信息

class UserSingleView(APIView):       #单条查询,改,删除视图
    def get(self,request,pk):               
        user = User.objects.get(id=pk)      #查询单条集合对象
        ser = UserSerializers(instance=user)#序列化数据
        return Response(ser.data)

    def put(self,request,pk):        #修改
        user = User.objects.get(pk=pk)
        ser = UserSerializers(instance=user,data=request.data)  #注意指定参数
        if ser.is_valid():
            ser.save()
            return Response(ser.data,status=200)
        return Response(ser.errors)

    def delete(self,request,pk):     #删除操作
        User.objects.get(pk=pk).delete()   
        return Response(status=status.HTTP_200_OK)
代码说明:
1. 使用类视图,定义两个类并继承APIView类视图;
2. 在类视图里编写:增删改查方法,通过HttpResponse返回状态。

serializers.py

from rest_framework import serializers #导入序列
from .models import User #导入表
class UserSerializers(serializers.Serializer):#注意继承的类
    nick_name = serializers.CharField(max_length=20,required=True)    #required=True设置必须验证
    gender = serializers.BooleanField(default=0,required=False)
   def create(self, validated_data):         #创建数据的操作
        return User.objects.create(**validated_data)

   def update(self, instance, validated_data):#修改数据的操作
      instance接收的是数据库查询的单个对象,validated_data为前端传输的数据

        instance.nick_name = validated_data.get('nick_name',instance.nick_name) 
        instance.gender = validated_data.get('gender',instance.gender)
        instance.save()                  #取出值每个字段进行保存
        return instance

版本二(使用混合 mixins)

继承generics和mixins里的方法,称之为“混合”
views.py:

from rest_framework import mixins, generics  # 导入相应模块
# mixins就是一个类,只不过这个类里定义了很多操作数据的方法
from .serializers import UserModelSerializer
class UserGenericAPIview(generics.GenericAPIView,mixins.ListModelMixin,mixins.CreateModelMixin):
    queryset = UserInfo.objects.all()      # queryset指定集合数据是从哪个数据库来
    serializer_class =UserModelSerializer  # serializer_class配置序列化器类UserModelSerializer

    # 调用mixins.ListModelMixin类的list()方法
    def get(self,request):
        return self.list(request)

    # 调用mixins.CreateModelMixin类的create()方法 
    def post(self,request):
        return self.create(request)

class UserGenericSingleView(generics.GenericAPIView,mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin):
    queryset = UserInfo.objects.all()
    serializer_class = UserModelSerializer

    # 调用mixins.RetrieveModelMixin类的retrieve()方法
    def get(self,request,pk):  #检索
        return self.retrieve(request)

    # 调用mixins.UpdateModelMixin类的update()方法
    def put(self,request,pk):  #修改
        return self.update(request)

    # 调用mixins.DestroyModelMixin类的destroy()方法
    def delete(self,request,pk):  #破坏
        return self.destroy(request)

代码说明:
1. 为什么要继承mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin等这一堆方法呢? 
答:比如我们自定义写了delete方法,而这个方法会自动、只能的去调用mixins.DestroyModelMixin这个类里面的动作。

serializers.py

from rest_framework import serializers
from .models import UserInfo

class UserModelSerializer(serializers.ModelSerializer):
    class Meta:
        #配置model为UserInfo
        model = UserInfo  
        fields = "__all__"   #fields配置要序列化的字段,"__all__"表示所有的字段都序列化

在上个版本中,queryset和serializer属性都是通过自己声明去使用的;

这个版本继承使用混合继承了generics,通过查看generics源码发现如下:

	class GenericAPIView(views.APIView):
···
    queryset = None
    serializer_class = None
···

版本三(使用混合高级版)

views.py:

from rest_framework import generics

class UserListAPIView(generics.ListCreateAPIView):
    queryset = UserInfo.objects.all()
    serializer_class = UserModelSerializer

class UserSingleView(generics.RetrieveUpdateDestroyAPIView):
    queryset = UserInfo.objects.all()
    serializer_class = UserModelSerializer

这几行代码搞定上面所有功能,只需要传入queryset和serializer即可,这什么原理呢?

1、第二版本中,我们继承了generics.GenericAPIView类视图,自己写了两个get和post方法对吧,那generics的另一个方法把这两个事情也干了,我们只需要继承即可。
2、对的,这个方法就是generics.ListCreateAPIView,我们且看看它的源码,你就明白了

class ListCreateAPIView(mixins.ListModelMixin,
                        mixins.CreateModelMixin,
                        GenericAPIView):       
    """
    Concrete view for listing a queryset or creating a model instance.
    """
    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

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

版本四(视图集 ViewSet)

views.py:

from rest_framework import viewsets,mixins
class GennericViewsSet(viewsets.GenericViewSet,
                       mixins.CreateModelMixin,
                       mixins.ListModelMixin,
                       mixins.RetrieveModelMixin,
                       mixins.UpdateModelMixin,
                       mixins.DestroyModelMixin
                       ):
    queryset = UserInfo.objects.all()
    serializer_class = Userserializer

这个版本views里就写了一个类视图,之前的所有版本都是写一个List和一个Detail视图的,

这个类 继承了viewsets.GenericViewSet,其他的方法都是mixins的viewsets

GenericViewSet继承了ViewSetMixin方法,从ViewSetMixin的源码里能看到可以改写as_view的信息,来达到定制路由的效果

class ViewSetMixin(object):
    @classonlymethod
    def as_view(cls, actions=None, **initkwargs):
      ······
        if not actions:
            raise TypeError("The `actions` argument must be provided when "
                            "calling `.as_view()` on a ViewSet. For example "
                            "`.as_view({'get': 'list'})`")

urls.py:

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$',views.GennericViewsSet.as_view({
    
    'get':'list',"post": "create"})),   #注意这里的写法
    url(r'^users/(?P<pk>\d+)/$',views.GennericViewsSet.as_view({
    
    'get':'retrieve','put':'update','delete':'destroy'}))
]

版本五 (终极版:写项目选用此法)

views.py:

 from rest_framework.viewsets import ModelViewSet
 class ZhongJiBanView(ModelViewSet):
     queryset = UserInfo.objects.all()
     serializer_class = UserModelSerializer

直接继承了一个巨无霸(ModelViewSet),这个巨无霸将所有的功能都封装到一块。相当于把我们从第一版到第三版写的所有事情都干了,
按照老规矩,我们来看看它的源码:

class ModelViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet):
    """
    A viewset that provides default `create()`, `retrieve()`, `update()`,
    `partial_update()`, `destroy()` and `list()` actions.
    """
    pass

从源码中能看出,ModelViewSet所继承的视图类
urls.py

1 from . import views
2 from rest_framework.routers import DefaultRouter
3 rount = DefaultRouter()
4 rount.register('user',views.ZhongjiBanView)
5 urlpatterns = []
6 urlpatterns += rount.urls

最终版的规则使用了drf的DefaultRouter函数,通过实例化DefaultRouter得到route对象,使用route.register()你的app路由,有多个注册多个即可

猜你喜欢

转载自blog.csdn.net/weixin_44121790/article/details/104602699
今日推荐