十、REST framework接口开发:基于GenericAPIView接口实现
前言:
使用GenericAPIView把代码逻辑中写死的变量全部参数化,后续如果想编写其他单表的接口时,只需要修改queryset和serializer_class,大大减少了代码的维护成本
实现:
1、针对复杂逻辑的接口,我们使用APIView进行接口开发,但是对于单表,DRF内部提供了自己的一套逻辑,APIView已经写过随笔,当前随笔,讲解GenericAPIView
请注意:之前我们重写了APIView方法,在使用GenericAPIView时,最好不要修改继承关系
下面的步骤,虽然最终版是ModelViewSet,最好一步一步的跟着操作,有助于了解整个DRF的工作流程
APIView->GenericAPIView->mixins->ListCreateAPIView->ModelViewSet
2、使用GenericAPIView实现接口的增删改查查
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.generics import GenericAPIView class RequestDataView(GenericAPIView): # 认证类,没有时为空 authentication_classes = [] permission_classes = [] # GenericAPIView提供了两个变量分别是 queryset 和 serializer_class # queryset 存放数据使用 queryset = Interface_case_data.objects.all() # 存放序列化器类 serializer_class = CaseDataSerializer # 新建get方法 def get(self, request, *args, **kwargs): # 使用 get_queryset 方法获取 queryset 的值 queryset = self.get_queryset() # 使用 get_serializer 方法获取序列化器,并对序列化器进行操作 ser = self.get_serializer(instance=queryset, many=True) # 返回序列化后的数据 return Response(ser.data) # 新建post方法 def post(self, request, *args, **kwargs): ser = self.get_serializer(data=request.data) # ser.is_valid(),校验字段方法,根据序列化器 if ser.is_valid(): ser.save() # ser.data为默认写法,数据从ser.data中获取,详细逻辑查看源码 return Response(ser.data) else: # 当序列化错误时,错误信息字段写入ser.errors,如:字段过长等信息 return Response(ser.errors) class RequestDataDetailView(GenericAPIView): # 认证类,没有时,注释掉 authentication_classes = [] permission_classes = [] queryset = Interface_case_data.objects.all() serializer_class = CaseDataSerializer # 结合get方法使用,默认值为lookup_field="pk" lookup_field = 'id' # 单查询 def get(self, request, *args, **kwargs): # get_object 根据pk值获取对象,GenericAPIView内部定义了lookup_field=pk,默认通过url中的有名分组pk进行取值,有名分组在路由中可以查看 # 如果想修改默认值,添加 lookup_field = xxx 即可 ser = self.get_serializer(instance=self.get_object()) # 序列化 return Response(ser.data) # 返回 # 单条数据更新,演示m2m数据更新,当没有m2m时,手动处理逻辑 def put(self, request, *args, **kwargs): # 进行序列化 ser = self.get_serializer(instance=self.get_object(), data=request.data) if ser.is_valid(): # 验证字段,注意:验证字段根据data进行验证 # 根据save方法,当instance不为空时,调用update方法 ser.save() return Response(ser.data) else: return Response(ser.errors) def delete(self, request, *args, **kwargs): self.get_object().delete() return Response()
3、路由配置信息
urlpatterns = [ path('api/<str:version>/user/', views.RequestDataView.as_view()), # 请注意:有名分组(?P<id>\d+),不过不想定义lookup_field = 'id',把id换成pk即可 re_path("api/(?P<version>.+)/user/(?P<id>\d+)", views.RequestDataDetailView.as_view()), ]

浙公网安备 33010602011771号