专题四:类视图

2022-04-18  本文已影响0人  龙猫六六

本章节介绍基于DRF类视图,以Host的增删改差的功能实现,分别介绍APIView,Mixins,Generic三个类视图介绍。APIView,Mixins,Generic之间的关系:最基础的是APIView。Mixins,Generic分别对Mixins,Generic封装

精华

image.png image.png

通用代码

本文定义host的model和序列化,示例代码如下:

# model.py
class Host(models.Model):
    """
    域名
    """
    name = models.CharField(max_length=50, verbose_name="名称")
    host = models.CharField(max_length=1024, verbose_name="host地址")
    description = models.CharField(max_length=1024, blank=True, null=True, verbose_name="描述")
    project = models.ForeignKey(Project, on_delete=models.CASCADE, verbose_name="项目归属", related_name="host_list")
    create_time = models.DateTimeField(auto_now_add=True, null=True, verbose_name="创建时间")

# serialzers.py
class HostSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Host
        # __all__会把数据库对应的字段都返回
        # 包括id,host的model对应外键的project以project存储和返回
        fields = "__all__"

APIView

APIView是DRF中类视图最基础的父类。用法与django中的view一致,自己分别实现get,post,put,delete等方法。

1.get请求:根据传参pk是否为空,实现目标host查询和所有host获取。需要定义两个路由来实现,具体参考示例的url.py。
2.post请求:新建host记录,models.objects.create(必须字段),然后序列化返回给前端
3.put请求:更新host记录,序列化的优势就出来了:
赋值serializer = serializers.HostSerializer(host, data=request.data), host为修改的模型对象,request.data为更新的参数
校验:serializer.is_valid():
保存:serializer.save()
4.delete请求:删除对应目标

目标host查询

url配置为host/apiview/<int:pk>,其中pk为默认的参数变量,与类视图get(self, request, pk)要保持一致;

所有host获取

url配置为host/apiview

类视图view.py
class HostAPIView(views.APIView):
    permission_classes = [IsAuthenticated]
    authentication_classes = [JWTAuthentication]

    def get(self, request, pk=None):
        """
        pk!=None,查询单个;pk=None,获取所有
        """
        if pk:
            host = models.Host.objects.get(pk=pk)
            serializer = serializers.HostSerializer(host)
            return Response(serializer.data)
        else:
            host = models.Host.objects.all()
            serializer = serializers.HostSerializer(host, many=True)
            return Response(serializer.data)

    def post(self, request):
        """
        新建
        """
        host = models.Host.objects.create(
            name=request.data.get('name'),
            host=request.data.get('host'),
            description=request.data.get('description'),
            project_id=request.data.get('project'),
        )
        serializer = serializers.HostSerializer(host)
        return Response(serializer.data)

    def put(self, request, pk):
        """
        更新
        """
        host = models.Host.objects.get(pk=pk)
        serializer = serializers.HostSerializer(host, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk):
        """
        删除
        """
        host = models.Host.objects.get(pk=pk)
        host.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
路由代码
#urls.py
urlpatterns = [
    path('host/apiview', views_clas.HostAPIView.as_view(), name='host_api_view'),
    path('host/apiview/<int:pk>', views_clas.HostAPIView.as_view(), name='host_api_view'),
              ] + router.urls
APIView类视图属性:

authentication_classes :认证方式,默认 api_settings.DEFAULT_AUTHENTICATION_CLASSES
throttle_classes:限流策略,默认api_settings.DEFAULT_THROTTLE_CLASSES
permission_classes:权限控制,默认api_settings.DEFAULT_PERMISSION_CLASSES

Mixins

mixins是组件的意思,在DRF中,针对增,删,改,查都有对应的mixins。Mixins是对APIView的封装,即对应的请求类型方法还需要申明,但对应请求类型方法的具体实现根据mixins封装方法实现。
generics.GenericAPIView:基础类,其属性queryset对应数据对象,serializer_class对应的序列化
mixins.ListModelMixin:get请求,获取列表,与RetrieveModelMixin不能共存(暂用get请求类型),self.list(request)
mixins.RetrieveModelMixin:get请求,检索查询,self.retrieve(request)
mixins.CreateModelMixin:post请求,新建对象,self.create(request)
mixins.UpdateModelMixin:put请求,更新对象,self.update(request)
mixins.DestroyModelMixin:delete请求,删除对象,self.destroy(request)

示例代码如下:

class HostMixinsViews(
    generics.GenericAPIView,
    mixins.CreateModelMixin,
    mixins.RetrieveModelMixin,
    mixins.ListModelMixin,
    mixins.UpdateModelMixin,
    mixins.DestroyModelMixin
):
    queryset = models.Host.objects.all()
    serializer_class = serializers.HostSerializer

    def get(self, request, pk=None):
        if pk:
            return self.retrieve(request)
        else:
            return self.list(request)

    def post(self, request):
        return self.create(request)

    def put(self, request, pk=None):
        return self.update(request)

    def delete(self, request, pk=None):
        return self.destroy(request)

通过继承generics.GenericAPIView, 可以设置queryset以及serializer_class,类视图函数就知道要处理哪个模型和序列化。

路由配置Mixins与APIView一致:

rlpatterns = [
    # apiview
    path('host/apiview', views_clas.HostAPIView.as_view(), name='host_api_view'),
    path('host/apiview/<int:pk>', views_clas.HostAPIView.as_view(), name='host_api_view'),
    # mixins
    path('host/mixins', views_clas.HostMixinsViews.as_view(), name='host_mixins_view'),
    path('host/mixins/<int:pk>', views_clas.HostMixinsViews.as_view(), name='host_mixins_view'),
              ] + router.urls

Generic

Generic是在Mixins上的进一步封装,通过显示的基础generic的子类快速实现对象的增删改差。有以下generic类视图:

generics.ListAPIView:实现获取列表的。实现get方法。
generics.CreateAPIView:实现创建数据的。实现post方法。
generics.UpdateAPIView:实现更新数据的。实现put方法。
generics.DestroyAPIView:实现删除数据的。实现delete方法。
generics.RetrieveAPIView:实现检索数据的。
generics.ListCreateAPIView:实现列表和创建数据的。
generics.RetrieveUpdateAPIView:实现检索和更新数据的。
generics.RetrieveDestroyAPIView:实现检索和删除数据的。
generics.RetrieveUpdateDestroyAPIView:实现检索和更新和删除数据的。

Host示例代码如下:
class HostGenericViews(
    generics.CreateAPIView,
    generics.UpdateAPIView,
    generics.DestroyAPIView,
    generics.RetrieveAPIView
):
    queryset = models.Host.objects.all()
    serializer = serializers.HostSerializer
路由代码如下:
urlpatterns = [
                  # apiview
                  path('host/apiview', views_clas.HostAPIView.as_view(), name='host_api_view'),
                  path('host/apiview/<int:pk>', views_clas.HostAPIView.as_view(), name='host_api_view'),
                  # mixins
                  path('host/mixins', views_clas.HostMixinsViews.as_view(), name='host_mixins_view'),
                  path('host/mixins/<int:pk>', views_clas.HostMixinsViews.as_view(), name='host_mixins_view'),
                  # generics
                  path('host/generics', views_clas.HostMixinsViews.as_view(), name='host_generics_view'),
                  path('host/generics/<int:pk>', views_clas.HostMixinsViews.as_view(), name='host_generics_view'),
              ] + router.urls

上一篇下一篇

猜你喜欢

热点阅读