Django里rest_framework的视图组件ModelViewSet进行优化视图

使用视图组件进行接口优化

  1. 使用视图组件的generics进行接口逻辑优化

    1. 导入ModelViewSet

      from rest_framework.viewsets import ModelViewSet
      
    2. 定义序列化类

      class BookSerializer(serializers.ModelSerializer):
        	class Meta:
            	model = 指定模型类
              fields = (指定验证字段)
              extra_kwargs = {"field_name":{"write_only":True}}
      
    3. 导入序列化类

      from .app_serializers import BookSerializer
      
    4. 定义视图类

      # 如果你的类只需要get和post方法你继承generics.ListCreateAPIView就可以了
      class BookView(ModelViewSet):
        	# queryset和serializer_class是固定的写法
        	# 指定queryset
        	queryset = BookInfo.objects.all()
          # 指定序列化类
          serializer_class = BookSerializer
      

GET获取全部数据和POST新增一条数据案列GET获取一条数据和PUT修改一条数据和DELETE删除一条数据

  1. 建立url

     re_path(r"^books/$", BookView.as_view({
         "get": "list",
         "post": "create"
     })),
    
     re_path(r"^books/(?P<pk>\d+)/$", BookView.as_view({
         "get": "retrieve",
         "put": "update",
         "delete": "destroy"
     }))
    
  2. 正则不取名叫pk会报一个Expected view BookFilterView to be called with a URL keyword argument named “pk”.的错误
    在这里插入图片描述

  3. 建立model

    from django.db import models
    
    from datetime import datetime
    # from django.contrib.auth.models import AbstractUser
    
    
    class AuthorInfo(models.Model):
        name = models.CharField(max_length=32, verbose_name="作者名称")
        age = models.IntegerField(verbose_name="作者年龄")
    
        class Meta:
            db_table = "db_author_info"
            verbose_name = "作者信息"
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.name
    
    
    class PublishInfo(models.Model):
        name = models.CharField(max_length=32, verbose_name="出版社名称")
        city = models.CharField(max_length=32, verbose_name="出版社所在城市")
        email = models.EmailField(verbose_name="出版社邮箱")
    
        class Meta:
            db_table = "db_publish_info"
            verbose_name = "出版社信息"
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.name
    
    
    class BookInfo(models.Model):
        title = models.CharField(max_length=32, verbose_name="书名")
        publishDate = models.DateField(default=datetime.now, verbose_name="出版日期")
    
        # max_digits小数位加整数位多少长度 decimal_places小数位长度为2
        price = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="图书价格")
        publish = models.ForeignKey(PublishInfo, related_name="book", related_query_name="book_query", on_delete=models.CASCADE, verbose_name="出版社")
        # ManyToManyField多对多
        authors = models.ManyToManyField(AuthorInfo, verbose_name="图书作者")
    
        class Meta:
            db_table = "db_book_info"
            verbose_name = "图书信息"
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.title
    
    
  4. 导入ModelViewSet

     from rest_framework.viewsets import ModelViewSet
    
  5. 定义序列化类

    from.models import BookInfo
    # 第一步: 导入模块
    from rest_framework import serializers
    
    class BookSerializer(serializers.ModelSerializer):
        class Meta:
            # 指定    要操作的模型类
            model = BookInfo
    
            # 指定序列化的字段
            fields = (
                "title",
                "price",
                "publishDate",
                "publish",
                "authors",
                "author_list",
                "publish_name",
                "publish_city"
            )
    
            # 指定那些字段是只写的
            # write_only只写的 (只写的 前端发送数据时要写它, 后端返回数据时没有它)
            extra_kwargs = {
                "publish": {"write_only": True},
                "authors": {"write_only": True}
            }
    
        # 自定义的字段
        # read_only只读的 (只读的 前端发送数据时不用写它, 后端返回数据时有它)
        publish_name = serializers.CharField(max_length=32, read_only=True, source="publish.name")
        publish_city = serializers.CharField(max_length=32, read_only=True, source="publish.city")
    
        author_list = serializers.SerializerMethodField()
    
        def get_author_list(self, book_obj):
            # 拿到queryset开始循环 [ {}, {}, {}]
            authors = []
    
            for author in book_obj.authors.all():
                authors.append(author.name)
            return authors
    
  6. 导入序列化类

    from .app_serializers import BookSerializer
    
  7. 定义视图类

    from rest_framework.viewsets import ModelViewSet
    
    from .models import BookInfo, PublishInfo, AuthorInfo
    from .app_serializers import BookSerializer
    
    class BookView(ModelViewSet):
        # queryset和serializer_class是固定的写法
        # 告诉它quertset是谁
        queryset = BookInfo.objects.all()
     
        # 告诉它序列化的类
        serializer_class = BookSerializer
    
  8. postman的GET请求所有数据
    在这里插入图片描述

  9. postman的POST请求所有数据
    在这里插入图片描述

  10. postman的GET请求获取一条数据
    在这里插入图片描述

  11. postman的PUT请求修改一条数据
    在这里插入图片描述

  12. postman的DELETE请求删除一条数据
    在这里插入图片描述

viewset源码剖析

  • Django程序启动, 开始初始化, 读取url.py, 读取settings, 读取视图类
  • 执行as_views(), BookView没有, 需要到父类(ModelViewSet)中找
  • ModelViewSet继承了mixin的几个Modelmixin和GenericViewSet, 显然ModelMixin也没有, 只有GenericViewSet中有
  • GenericViewSet没有任何代码, 只继承了ViewSetMixin和generics, GenericAPIView
  • 继续去ViewSetMixin中查找, 找到了as_view类方法, 在重新封装view函数的过程中, 有一个self.action_map = actions
  • 这个actions就是我们给as_view()传递的从参数
  • 绑定url和视图函数(actions)之间的映射关系
  • 等待用户请求
  • 接受到用户请求, 根据url找到视图函数
  • 执行视图函数的dispatch方法(因为视图函数的返回值是: return self.dispatch())
  • dispatch分发请求, 查找到视图类的五个方法中的某个
  • 开始执行, 比如post请求, 返回: self.create(), 视图类本身没有, 则会到父类中查找
  • 最后在CreateModelMixin中查找
  • 执行create()方法, 获取queryset和serializer_class
  • 返回数据

这就是viewset优化方案, 整个优化方案最重要的地方就是url.py中我们传入的参数, 然后对参数进行映射关系绑定

好的,下面是基于Djangorest_framework框架的ModelViewSet视图的源码解析: 1.基本介绍 ModelViewSet视图Django框架的rest_framework模块中的一个视图类,它继承了GenericAPIView和Mixins,提供了对资源的CRUD操作。ModelViewSet视图类中提供了一系列的方法,如list、create、retrieve、update、partial_update、destroy等,这些方法对应着HTTP请求中的GET、POST、PUT、PATCH、DELETE等动词。 2.源码解析 ModelViewSet视图的源码主要涉及到以下几个部分: (1)视图类的定义 ``` 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继承了CreateModelMixin、RetrieveModelMixin、UpdateModelMixin、DestroyModelMixin和ListModelMixin这些视图混合类,以及GenericViewSet类。 (2)视图方法的实现 a. list方法 ``` def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset()) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) return Response(serializer.data) ``` list方法用于返回资源列表,它首先通过get_queryset方法获取查询集,然后通过filter_queryset方法对查询集进行过滤,最后通过get_serializer方法将查询集序列化为JSON数据返回给客户端。 b. create方法 ``` def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) self.perform_create(serializer) headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) ``` create方法用于创建资源,它首先通过get_serializer方法获取序列化器,然后通过perform_create方法进行资源的创建,最后返回HTTP 201 Created状态码以及资源的JSON数据。 c. retrieve方法 ``` def retrieve(self, request, *args, **kwargs): instance = self.get_object() serializer = self.get_serializer(instance) return Response(serializer.data) ``` retrieve方法用于获取单个资源,它通过get_object方法获取资源实例,然后通过get_serializer方法将资源实例序列化为JSON数据返回给客户端。 d. update方法 ``` def update(self, request, *args, **kwargs): partial = kwargs.pop('partial', False) instance = self.get_object() serializer = self.get_serializer(instance, data=request.data, partial=partial) serializer.is_valid(raise_exception=True) self.perform_update(serializer) return Response(serializer.data) ``` update方法用于更新资源,它首先通过get_object方法获取资源实例,然后通过get_serializer方法获取序列化器,最后通过perform_update方法进行资源的更新,最终返回更新后的资源JSON数据。 e. partial_update方法 ``` def partial_update(self, request, *args, **kwargs): kwargs['partial'] = True return self.update(request, *args, **kwargs) ``` partial_update方法用于部分更新资源,它通过调用update方法,并将partial参数设置为True,进行资源的部分更新。 f. destroy方法 ``` def destroy(self, request, *args, **kwargs): instance = self.get_object() self.perform_destroy(instance) return Response(status=status.HTTP_204_NO_CONTENT) ``` destroy方法用于删除资源,它首先通过get_object方法获取资源实例,然后通过perform_destroy方法进行资源的删除,最终返回HTTP 204 No Content状态码。 3.总结 ModelViewSet视图Django框架的rest_framework模块中的一个视图类,它继承了GenericAPIView和Mixins,提供了对资源的CRUD操作。通过对视图类的源码解析,我们可以深入了解ModelViewSet视图的内部实现,从而更好地理解和使用该视图类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

只因为你温柔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值