如何在Django的类B中调用类A的create、update等CRUD方法?
在Django ViewSet中跨类调用其他ViewSet的方法
当然可以在类B的create方法中调用类A的create和update方法,下面是两种可行的实现方式:
方式一:直接实例化类A并调用方法
由于ViewSet的方法是实例方法,你需要先创建类A的实例,并为其设置必要的请求相关属性,再调用对应方法:
from rest_framework import viewsets, status from rest_framework.response import Response class A(viewsets.ModelViewSet): def create(self, request, *args, **kwargs): # 类A的create逻辑 serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) self.perform_create(serializer) return Response(serializer.data, status=status.HTTP_201_CREATED) def update(self, request, *args, **kwargs): # 类A的update逻辑 instance = self.get_object() serializer = self.get_serializer(instance, data=request.data) serializer.is_valid(raise_exception=True) self.perform_update(serializer) return Response(serializer.data) class B(viewsets.ModelViewSet): def create(self, request, *args, **kwargs): # 类B自身的前置处理逻辑 # 实例化类A并设置必要属性 a_viewset = A() a_viewset.request = request a_viewset.action = "create" # 部分ViewSet方法依赖action属性,需手动设置 a_viewset.queryset = A.queryset # 若A中定义了queryset,需同步设置 # 调用类A的create方法 a_create_response = a_viewset.create(request, *args, **kwargs) # 调用类A的update方法(注意update通常需要传入目标实例的pk) # 示例:更新pk为1的实例 # a_update_response = a_viewset.update(request, pk=1, *args, **kwargs) # 类B自身的后置处理逻辑 return a_create_response # 或返回自定义响应
方式二:提取公共逻辑到Mixin类(推荐)
直接跨ViewSet实例调用方法可能会引入状态依赖问题,更优雅的做法是把类A中create和update的核心逻辑提取到Mixin类中,让类A和类B都继承这个Mixin实现代码复用:
from rest_framework import viewsets, status from rest_framework.response import Response class ALogicMixin: def _create_core(self, request, *args, **kwargs): # 提取类A create方法的核心逻辑 serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) self.perform_create(serializer) return serializer.data def _update_core(self, request, *args, **kwargs): # 提取类A update方法的核心逻辑 instance = self.get_object() serializer = self.get_serializer(instance, data=request.data) serializer.is_valid(raise_exception=True) self.perform_update(serializer) return serializer.data class A(ALogicMixin, viewsets.ModelViewSet): def create(self, request, *args, **kwargs): data = self._create_core(request, *args, **kwargs) return Response(data, status=status.HTTP_201_CREATED) def update(self, request, *args, **kwargs): data = self._update_core(request, *args, **kwargs) return Response(data) class B(ALogicMixin, viewsets.ModelViewSet): def create(self, request, *args, **kwargs): # 类B自身逻辑 # 调用类A的核心create逻辑 create_data = self._create_core(request, *args, **kwargs) # 调用类A的核心update逻辑(需传入对应实例的pk) # update_data = self._update_core(request, pk=some_pk, *args, **kwargs) # 自定义响应处理 return Response(create_data, status=status.HTTP_201_CREATED)
这种方式遵循DRY(Don't Repeat Yourself)原则,代码复用性更强,也避免了直接实例化ViewSet带来的潜在状态问题。
内容的提问来源于stack exchange,提问作者Adarsh Srivastav
相关产品推荐
相关产品推荐

