十三、REST framework接口开发:基于ModelViewSet接口实现<终版>

1、十二节 https://www.cnblogs.com/guanyf/p/18650421 让我们了解到可以通过路由分发我们定义的函数方法,回到我们 十一节 https://www.cnblogs.com/guanyf/p/18649260中的代码中,也支持这样的操作

class CaseDataSerializer(serializers.ModelSerializer):

    class Meta:
        model = Interface_case_data
        fields = ["parent_id", "interface_case_name", "request_data", "request_expected_results"]

    # 重写父类的create方法
    def create(self, validated_data):
        # 获取数据库对象
        case_data = Interface_case_data.objects.create(**self.validated_data)
        return case_data

    # 重写父类的update方法
    def update(self, instance, validated_data):
        # pk=instance.pk 获取修改数据的主键
        Interface_case_data.objects.filter(pk=instance.pk).update(**validated_data)
        # 修改完成后,获取新数据进行返回
        updated_case = Interface_case_data.objects.get(pk=instance.pk)
        return updated_case


from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin
from rest_framework.viewsets import GenericViewSet


# 1、在十一节中使用ListCreateAPIView,本质就是继承ListModelMixin, CreateModelMixin, GenericAPIView
# 2、为了支持分发机制,除了GenericAPIView,DRF还提供了GenericViewSet类,此类在GenericAPIView的基础上支持了路由分发机制
# 3、替换GenericAPIView,改为 GenericViewSet
# 4、通过学习知道,使用ListCreateAPIView不通过路由分发时,使用它自己的post和get方法,而get和post方法本质就是调用的
# ListModelMixin, CreateModelMixin中的list 和 create方法,那么我们可以在路由中直接定义这两个方法
# 5、在学习ViewSet时,我们把增删改查查五个接口放在了一个类中,以此为例,我们也可以把单条数据的RetrieveUpdateDestroyAPIView放到
# 一个类中,该类也是整合mixins.RetrieveModelMixin,mixins.UpdateModelMixin, mixins.DestroyModelMixin等各种类,那么我们也可
# 以直接指定它们本身的删、改、查方法,分别是:retrieve、update、destroy
class RequestDataView(ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericViewSet):
    # 认证类,没有时为空
    authentication_classes = []
    permission_classes = []
    # GenericAPIView提供了两个变量分别是 queryset 和 serializer_class
    # queryset 存放数据使用
    queryset = Interface_case_data.objects.all()
    # 存放序列化器类
    serializer_class = CaseDataSerializer
    # 结合get方法使用,默认值为lookup_field="pk"
    lookup_field = 'id'

2、路由配置

urlpatterns = [
    # 通过路由分发ListModelMixin, CreateModelMixin中的list 和 create方法
    path('api/<str:version>/user/', views.RequestDataView.as_view({"get": "list", "post": "create"})),
    # 请注意:有名分组(?P<id>\d+),不过不想定义lookup_field = 'id',把id换成pk即可
    # 通过路由分发RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin的retrieve、update、destroy方法
    re_path("api/(?P<version>.+)/user/(?P<id>\d+)", views.RequestDataView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
]

3、发现继承的类太多,没关系,DRF提供了ModelViewSet类,此类就是整合我们继承的类,修改我的的视图类

# 继承过长没关系,DRF提供了ModelViewSet类,此类就是整合我们继承的类
from rest_framework.viewsets import ModelViewSet


class RequestDataView(ModelViewSet):
    # 认证类,没有时为空
    authentication_classes = []
    permission_classes = []
    # GenericAPIView提供了两个变量分别是 queryset 和 serializer_class
    # queryset 存放数据使用
    queryset = Interface_case_data.objects.all()
    # 存放序列化器类
    serializer_class = CaseDataSerializer
    # 结合get方法使用,默认值为lookup_field="pk"
    lookup_field = 'id'

4、路由配置可以通过注册的形式自动生成配置,修改路由

# 创建路由器实例
router = routers.DefaultRouter()
# 注册视图集
router.register('user', views.RequestDataView)
# 获取URL模式,获取由路由器生成的URL模式列表,并将其赋值给urlpatterns变量
urlpatterns = router.urls

5、使用ModelViewSet时,版本控制可以通过设置路由进行控制,请注意:设置后,url请求必须携带版本信息

# 创建路由器实例
router = routers.DefaultRouter()
# 注册视图集
router.register(r'user', views.RequestDataView)
# 获取URL模式,获取由路由器生成的URL模式列表,并将其赋值给urlpatterns变量
# urlpatterns = router.urls

# 配置路由信息 <str:version>/ 配置后访问接口必须携带版本信息,如 /v1/user/
urlpatterns = [
    path('<str:version>/', include(router.urls)),
]

6、配置版本后,在视图中,我们可以根据版本信息不同,重写 get_serializer_class方法,以便于根据版本修改序列化器对数据的操作。

class RequestDataView(ModelViewSet):
    # 认证类,没有时为空
    authentication_classes = []
    permission_classes = []
    # GenericAPIView提供了两个变量分别是 queryset 和 serializer_class
    # queryset 存放数据使用
    queryset = Interface_case_data.objects.all()
    # 存放序列化器类
    serializer_class = CaseDataSerializer
    # 结合get方法使用,默认值为lookup_field="pk"
    lookup_field = 'id'
    
    # 重写 get_serializer_class 方法
    def get_serializer_class(self):
        if self.request.version == 'v1':
            return self.serializer_class1
        return self.serializer_class2

总结:学到这里,基本DRF已经完全掌握,最好自己手动敲一遍才能发现中间的问,如有问题请留言。

posted @ 2025-01-03 17:13  蜗牛·哥  阅读(19)  评论(0)    收藏  举报