自动化测试平台开发(七):接口测试 - DRF编写后端接口实现增、删、改、查

本篇讲解如果用djangorestframwork编写后端接口,事件数据表增删改查。这里只记录接口信息表的后端接口请求实现。

后端接口实现

一、自定义、封装

  1. 自定义Response,统一接口返回数据格式,便于前端请求数据解析。
  2. 自定义Pagination,定制分页,接口、用例数据量会比较大,查询最好分页查询
  3. 封装DRF ModelViewSet,应用自定义Response、自定义Pagination、django filters、登录认证等
  4. rest_framework_bulk 封装实现批量处理
  1 #!/usr/bin/python
  2 # -*- coding:utf-8 _*- 
  3 """
  4 @author:TXU
  5 @file:base.py
  6 @time:2021/08/24
  7 @email:tao.xu2008@outlook.com
  8 @description:
  9 """
 10 from collections import OrderedDict
 11 import six
 12 from django.db.models import Count, Sum
 13 from rest_framework.response import Response
 14 from rest_framework.serializers import Serializer
 15 from rest_framework.pagination import PageNumberPagination
 16 from rest_framework.viewsets import ModelViewSet, GenericViewSet
 17 from rest_framework_bulk import BulkModelViewSet
 18 from rest_framework import filters
 19 from django_filters.rest_framework import DjangoFilterBackend
 20 from rest_framework.permissions import IsAuthenticated
 21 from apps.api_test import logger
 22 
 23 
 24 class JsonResponse(Response):
 25     """
 26     An HttpResponse that allows its data to be rendered into
 27     arbitrary media types.
 28     """
 29 
 30     def __init__(self, data=None, code=2, msg='ok', success='true',
 31                  status=None,
 32                  template_name=None, headers=None,
 33                  exception=False, content_type=None):
 34         """
 35         Alters the init arguments slightly.
 36         For example, drop 'template_name', and instead use 'data'.
 37         Setting 'renderer' and 'media_type' will typically be deferred,
 38         For example being set automatically by the `APIView`.
 39         """
 40         super(Response, self).__init__(None, status=status)
 41         if isinstance(data, Serializer):
 42             msg = (
 43                 'You passed a Serializer instance as data, but '
 44                 'probably meant to pass serialized `.data` or '
 45                 '`.error`. representation.'
 46             )
 47             raise AssertionError(msg)
 48         self.data = {"code": code, "msg": msg, "success": success, "data": data}
 49         self.template_name = template_name
 50         self.exception = exception
 51         self.content_type = content_type
 52 
 53         if headers:
 54             for name, value in six.iteritems(headers):
 55                 self[name] = value
 56 
 57 
 58 # 定制化分页
 59 class Pagination(PageNumberPagination):
 60     def get_paginated_response(self, data):
 61         return Response(OrderedDict([
 62             ('count', self.page.paginator.count),
 63             ('page', self.page.number),
 64             ('list', data)
 65         ]))
 66 
 67     page_size = 20
 68     page_query_param = 'page'  # 页码的名称
 69     page_size_query_param = 'page_size'  # 每页多少条
 70     max_page_size = 10000
 71 
 72 
 73 class TotalCountModelMixin(GenericViewSet):
 74     """Total count a queryset."""
 75     def list(self, request, *args, **kwargs):
 76         queryset = self.filter_queryset(self.get_queryset())
 77         return JsonResponse(data={'total': queryset.count()}, status=200)
 78 
 79 
 80 class GroupCountModelMixin(GenericViewSet):
 81     """Count a queryset by group."""
 82     filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
 83     default_group_by_field = 'id'  # string, field
 84     default_time_unit = ''  # string, type(group_by_field)=DateTimeField --> year | month | day
 85     time_unit_str = {
 86         'year': '%%Y',
 87         'month': '%%Y-%%m',
 88         'week': '%%x-%%v',
 89         'day': '%%Y-%%m-%%d',
 90     }
 91 
 92     def list(self, request, *args, **kwargs):
 93         """
 94         分组查询
 95         :param request:
 96             group_by_field: 分组字段
 97             time_unit: 若按时间分组,可设置时间单位 year | month | day
 98         :param args:
 99         :param kwargs:
100         :return:
101         """
102         group_by_field = self.default_group_by_field
103         time_unit = self.default_time_unit
104         if 'group_by_field' in request.query_params:
105             request.query_params._mutable = True
106             group_by_field = request.query_params.get('group_by_field')
107             request.query_params.__delitem__('group_by_field')
108             request.query_params._mutable = False
109 
110         if 'time_unit' in request.query_params:
111             request.query_params._mutable = True
112             time_unit = request.query_params.get('time_unit')
113             request.query_params.__delitem__('time_unit')
114             request.query_params._mutable = False
115 
116         extra_select = {
117             group_by_field: "DATE_FORMAT({}, '{}')".format(group_by_field, self.time_unit_str[time_unit])
118         } if time_unit else {}
119         queryset = self.filter_queryset(self.get_queryset().extra(select=extra_select).values(group_by_field)).\
120             order_by(group_by_field).annotate(count=Count("id")).values(group_by_field, "count")
121         return JsonResponse(data=list(queryset.all()), status=200)
122 
123 
124 class ApiTestBaseViewSet(BulkModelViewSet):
125     # 登录认证
126     # permission_classes = [IsAuthenticated, ]
127     filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
128     pagination_class = Pagination  # 分页
129 
130     # 创建数据
131     def create(self, request, *args, **kwargs):
132         response = super().create(request, *args, **kwargs)
133         return JsonResponse(response.data, status=response.status_code)
134 
135     # 检索数据
136     def retrieve(self, request, *args, **kwargs):
137         response = super().retrieve(request, *args, **kwargs)
138         return JsonResponse(response.data, status=response.status_code)
139 
140     # 更新数据
141     def update(self, request, *args, **kwargs):
142         kwargs['partial'] = True  # 强制修改为 局部更新数据
143         response = super().update(request, *args, **kwargs)
144         return JsonResponse(response.data, status=response.status_code)
145 
146     # 局部更新数据
147     def partial_update(self, request, *args, **kwargs):
148         response = super().partial_update(request, *args, **kwargs)
149         return JsonResponse(response.data, status=response.status_code)
150 
151     # 批量 更新数据
152     def bulk_update(self, request, *args, **kwargs):
153         response = super().bulk_update(request, *args, **kwargs)
154         return JsonResponse(response.data, status=response.status_code)
155 
156     # 批量 局部更新数据
157     def partial_bulk_update(self, request, *args, **kwargs):
158         response = super().partial_bulk_update(request, *args, **kwargs)
159         return JsonResponse(response.data, status=response.status_code)
160 
161     # 删除数据
162     def destroy(self, request, *args, **kwargs):
163         response = super().destroy(request, *args, **kwargs)
164         return JsonResponse(response.data, status=200)
165 
166     # 批量 删除数据执行条件
167     def allow_bulk_destroy(self, qs, filtered):
168         print(qs.count())
169         print(filtered.count())
170         return (qs is not filtered) and self.request.query_params and qs.count() > filtered.count()
171 
172     # 批量 删除数据
173     def bulk_destroy(self, request, *args, **kwargs):
174         response = super().bulk_destroy(request, *args, **kwargs)
175         if response.status_code == 400:
176             return JsonResponse(None, msg="筛选参错误/空,禁止全表删除!", code=500500, status=200)
177         return JsonResponse(response.data, status=200)
178 
179     # 查询数据
180     def list(self, request, *args, **kwargs):
181         response = super().list(request, *args, **kwargs)
182         return JsonResponse(response.data, status=response.status_code)
183 
184 
185 if __name__ == '__main__':
186     pass
View Code

 

二、为每个表定义一个或多个序列化器,serializers

  1 #!/usr/bin/python
  2 # -*- coding:utf-8 _*- 
  3 """
  4 @author:TXU
  5 @file:serializers.py
  6 @time:2021/08/23
  7 @email:tao.xu2008@outlook.com
  8 @description:
  9 """
 10 from django.contrib.auth.models import User
 11 from rest_framework import serializers
 12 from rest_framework_bulk import BulkSerializerMixin, BulkListSerializer
 13 from rest_framework.authtoken.models import Token
 14 
 15 from apps.api_test.models import Department, Project, ProjectDynamic, ProjectMember, \
 16     AppSetting, GlobalEnv, GlobalConst, GlobalHeader, GlobalResponseValidate, \
 17     ApiGroup, ApiInfo, ApiUpdateHistory, YApiEvent, GlobalLabel, \
 18     TestSuite, TestCase, TestStep, TestReport, TestTask, TestEnvMonitor
 19 
 20 
 21 class TokenSerializer(serializers.ModelSerializer):
 22     """
 23     用户信息序列化
 24     """
 25     first_name = serializers.CharField(source="user.first_name")
 26     last_name = serializers.CharField(source="user.last_name")
 27     phone = serializers.CharField(source="user.user.phone")
 28     email = serializers.CharField(source="user.email")
 29     date_joined = serializers.CharField(source="user.date_joined")
 30 
 31     class Meta:
 32         model = Token
 33         # fields = '__all__'
 34         fields = ('first_name', 'last_name', 'phone', 'email', 'key', 'date_joined')
 35 
 36 
 37 class UserSerializer(serializers.ModelSerializer):
 38 
 39     class Meta:
 40         model = User
 41         fields = ('id', 'username', 'first_name', 'last_name', 'email')
 42 
 43 
 44 class DepartmentSerializer(serializers.ModelSerializer):
 45     """
 46     部门信息序列化
 47     """
 48     class Meta:
 49         model = Department
 50         fields = '__all__'
 51 
 52 
 53 class DepartmentDeserializer(BulkSerializerMixin, serializers.ModelSerializer):
 54     """
 55     部门信息反序列化
 56     """
 57     class Meta:
 58         model = Department
 59         fields = '__all__'
 60         list_serializer_class = BulkListSerializer
 61 
 62 
 63 class ProjectSerializer(serializers.ModelSerializer):
 64     """
 65     项目信息序列化
 66     """
 67     create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
 68     update_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
 69     creator = UserSerializer()
 70     updater = UserSerializer()
 71     department = DepartmentSerializer()
 72 
 73     class Meta:
 74         model = Project
 75         fields = '__all__'
 76 
 77 
 78 class ProjectDetailSerializer(serializers.ModelSerializer):
 79     """
 80     项目信息序列化
 81     """
 82     toUpdateApiCount = serializers.SerializerMethodField()
 83     toVerifyApiCount = serializers.SerializerMethodField()
 84     updatedApiCount = serializers.SerializerMethodField()
 85     apiCount = serializers.SerializerMethodField()
 86     apiNoCaseCount = serializers.SerializerMethodField()
 87     apiCoverage = serializers.SerializerMethodField()
 88     apiPassRate = serializers.SerializerMethodField()
 89     stepCount = serializers.SerializerMethodField()
 90     dynamicCount = serializers.SerializerMethodField()
 91     memberCount = serializers.SerializerMethodField()
 92     create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
 93     update_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
 94     creator = UserSerializer()
 95     updater = UserSerializer()
 96     department = DepartmentSerializer()
 97 
 98     class Meta:
 99         model = Project
100         fields = ('id', 'name', 'version', 'department',
101                   'create_time', 'update_time', 'delete_time', 'is_delete', 'status', 'description',
102                   'creator', 'updater', 'apiCount', 'apiNoCaseCount', 'apiCoverage', 'stepCount',
103                   'apiPassRate', 'toUpdateApiCount', 'toVerifyApiCount', 'updatedApiCount',
104                   'dynamicCount', 'memberCount')
105 
106     def get_apiCount(self, obj):
107         return obj.api_project.filter(status__exact=True).count()
108 
109     def get_apiNoCaseCount(self, obj):
110         api_no_case_count = 0
111         for api in obj.api_project.filter(status__exact=True):
112             steps = api.step_api.filter(status__exact=True)
113             if steps.count() == 0:
114                 # 接口无测试步骤
115                 api_no_case_count += 1
116         return api_no_case_count
117 
118     def get_apiPassCount(self, obj):
119         api_pass_count = 0
120         for api in obj.api_project.filter(status__exact=True):
121             steps = api.step_api.filter(status__exact=True)
122             if steps.count() == 0:
123                 # 接口无测试步骤
124                 continue
125             fail_steps = steps.exclude(result__exact='passed')
126             if fail_steps.count() == 0:
127                 # 步骤全部通过
128                 api_pass_count += 1
129         return api_pass_count
130 
131     def get_apiPassRate(self, obj):
132         api_count = self.get_apiCount(obj)
133         if api_count == 0:
134             return 1
135         pass_count = self.get_apiPassCount(obj)
136         return round(pass_count / api_count, 3)
137 
138     def get_apiCoverage(self, obj):
139         api_count = obj.api_project.filter(status__exact=True).count()
140         if api_count == 0:
141             return 1
142 
143         api_count_with_case = 0
144         for api in obj.api_project.filter(status__exact=True):
145             if api.step_api.filter(status__exact=True).count() > 0:
146                 api_count_with_case += 1
147         return round(api_count_with_case/api_count, 3)
148 
149     def get_toUpdateApiCount(self, obj):
150         to_update_api_count = 0
151         for api in obj.api_project.filter(status__exact=True):
152             updates = api.update_api.filter(api__id__exact=api.id)
153             update_status_list = [u.update_status for u in updates]
154             if update_status_list and min(update_status_list) == 0:
155                 to_update_api_count += 1
156         return to_update_api_count
157         # return obj.api_project.filter(update_status__exact=0, status__exact=True).count()
158 
159     def get_toVerifyApiCount(self, obj):
160         to_verify_api_count = 0
161         for api in obj.api_project.filter(status__exact=True):
162             updates = api.update_api.filter(api__id__exact=api.id)
163             update_status_list = [u.update_status for u in updates]
164             if update_status_list and min(update_status_list) == 1:
165                 to_verify_api_count += 1
166         return to_verify_api_count
167         # return obj.api_project.filter(update_status__exact=1, status__exact=True).count()
168 
169     def get_updatedApiCount(self, obj):
170         updated_api_count = 0
171         for api in obj.api_project.filter(status__exact=True):
172             updates = api.update_api.filter(api__id__exact=api.id)
173             update_status_list = [u.update_status for u in updates]
174             if not update_status_list or min(update_status_list) == 2:
175                 updated_api_count += 1
176         return updated_api_count
177         # return obj.api_project.filter(update_status__exact=2, status__exact=True).count()
178 
179     def get_stepCount(self, obj):
180         # return obj.case_project.filter(status__exact=True).count()
181         case_count = 0
182         for api in obj.api_project.filter(status__exact=True):
183             case_count += api.step_api.filter(status__exact=True).count()
184         return case_count
185 
186     def get_dynamicCount(self, obj):
187         return obj.dynamic_project.all().count()
188 
189     def get_memberCount(self, obj):
190         return obj.member_project.all().count()
191 
192 
193 class ProjectDeserializer(BulkSerializerMixin, serializers.ModelSerializer):
194     """
195     项目信息反序列化
196     """
197     class Meta:
198         model = Project
199         fields = '__all__'
200         list_serializer_class = BulkListSerializer
201 
202 
203 class ProjectDynamicDeserializer(serializers.ModelSerializer):
204     """
205     项目动态信息反序列化
206     """
207     class Meta:
208         model = ProjectDynamic
209         fields = ('id', 'project', 'time', 'type', 'operationObject', 'user', 'description')
210 
211 
212 class ProjectDynamicSerializer(serializers.ModelSerializer):
213     """
214     项目动态信息序列化
215     """
216     operationUser = serializers.CharField(source='user.first_name')
217     time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
218 
219     class Meta:
220         model = ProjectDynamic
221         fields = ('id', 'time', 'type', 'operationObject', 'operationUser', 'description')
222 
223 
224 class ProjectMemberDeserializer(serializers.ModelSerializer):
225     """
226     项目成员信息反序列化
227     """
228     class Meta:
229         model = ProjectMember
230         fields = ('id', 'role', 'status', 'project', 'user')
231 
232 
233 class ProjectMemberSerializer(serializers.ModelSerializer):
234     """
235     项目成员信息序列化
236     """
237     user = UserSerializer(read_only=True)
238 
239     class Meta:
240         model = ProjectMember
241         fields = ('id', 'role', 'status', 'project', 'user')
242 
243 
244 class AppSettingSerializer(serializers.ModelSerializer):
245     """
246     env信息序列化
247     """
248     data = serializers.JSONField()
249 
250     class Meta:
251         model = AppSetting
252         fields = '__all__'
253 
254 
255 class GlobalEnvSerializer(BulkSerializerMixin, serializers.ModelSerializer):
256     """
257     env信息序列化
258     """
259     config = serializers.JSONField()
260     data = serializers.JSONField()
261     mock = serializers.JSONField()
262 
263     class Meta:
264         model = GlobalEnv
265         fields = '__all__'
266         list_serializer_class = BulkListSerializer
267 
268 
269 class GlobalConstSerializer(BulkSerializerMixin, serializers.ModelSerializer):
270     """
271     global const信息序列化
272     """
273 
274     class Meta:
275         model = GlobalConst
276         fields = '__all__'
277         list_serializer_class = BulkListSerializer
278 
279 
280 class GlobalHeaderSerializer(BulkSerializerMixin, serializers.ModelSerializer):
281     """
282     global const信息序列化
283     """
284 
285     class Meta:
286         model = GlobalHeader
287         fields = '__all__'
288         list_serializer_class = BulkListSerializer
289 
290 
291 class GlobalResponseValidateSerializer(BulkSerializerMixin, serializers.ModelSerializer):
292     """
293     GlobalResponseValidate信息序列化
294     """
295 
296     class Meta:
297         model = GlobalResponseValidate
298         fields = '__all__'
299         list_serializer_class = BulkListSerializer
300 
301 
302 class GlobalLabelSerializer(BulkSerializerMixin, serializers.ModelSerializer):
303     """
304     标签 信息序列化
305     """
306     type_name = serializers.SerializerMethodField()
307 
308     class Meta:
309         model = GlobalLabel
310         fields = ('id', 'name', 'type', 'type_name', 'status', 'description')
311         list_serializer_class = BulkListSerializer
312 
313     def get_type_name(self, obj):
314         return obj.get_type_display()
315 
316 
317 class ApiGroupSerializer(serializers.ModelSerializer):
318     """
319     接口一级分组信息序列化
320     """
321     project = ProjectSerializer()
322 
323     class Meta:
324         model = ApiGroup
325         fields = ('id', 'name', 'project',
326                   'create_time', 'update_time', 'delete_time', 'is_delete', 'status', 'description')
327 
328 
329 class ApiGroupDeserializer(BulkSerializerMixin, serializers.ModelSerializer):
330     """
331     接口一级分组信息反序列化
332     """
333     class Meta:
334         model = ApiGroup
335         fields = '__all__'
336         list_serializer_class = BulkListSerializer
337 
338 
339 class ApiInfoSerializer(serializers.ModelSerializer):
340     """
341     接口详细信息序列化
342     """
343     create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
344     update_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
345     creator = UserSerializer()
346     updater = UserSerializer()
347     project = ProjectSerializer()
348     api_group = ApiGroupSerializer()
349     labels = GlobalLabelSerializer(many=True, read_only=True)
350     update_status_name = serializers.SerializerMethodField()
351     test_case_count = serializers.SerializerMethodField()
352 
353     class Meta:
354         model = ApiInfo
355         fields = ('id', 'yapi_id', 'project', 'api_group', 'origin', 'name', 'http_type', 'method', 'path', 'host_tag',
356                   'yapi_req_headers', 'yapi_req_params', 'yapi_req_query', 'yapi_req_body_form', 'yapi_req_body_other', 'yapi_res_body',
357                   'req_headers', 'req_params', 'req_json', 'req_data', 'validator', 'update_status', 'labels',
358                   'create_time', 'update_time', 'delete_time', 'is_delete', 'status', 'description',
359                   'creator', 'updater', 'update_status_name', 'test_case_count')
360 
361     def get_update_status_name(self, obj):
362         return obj.get_update_status_display()
363 
364     def get_test_case_count(self, obj):
365         return obj.step_api.all().count()
366 
367 
368 class ApiInfoCountSerializer(serializers.ModelSerializer):
369     """接口统计信息序列化"""
370     api_count = serializers.SerializerMethodField()
371     toUpdateApiCount = serializers.SerializerMethodField()
372     toVerifyApiCount = serializers.SerializerMethodField()
373     updatedApiCount = serializers.SerializerMethodField()
374 
375 
376 class ApiInfoDeserializer(BulkSerializerMixin, serializers.ModelSerializer):
377     """
378     接口详细信息序列化
379     """
380     class Meta:
381         model = ApiInfo
382         fields = '__all__'
383         list_serializer_class = BulkListSerializer
384 
385 
386 class ApiUpdateHistorySerializer(serializers.ModelSerializer):
387     """
388     接口变更历史信息序列化
389     """
390     update_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
391     update_status_name = serializers.SerializerMethodField()
392 
393     class Meta:
394         model = ApiUpdateHistory
395         fields = ('id', 'api', 'event', 'content', 'updater', 'update_time', 'update_status', 'update_status_name')
396 
397     def get_update_status_name(self, obj):
398         return obj.get_update_status_display()
399 
400 
401 class ApiUpdateHistoryDeserializer(serializers.ModelSerializer):
402     """
403     接口变更历史信息反序列化
404     """
405     class Meta:
406         model = ApiUpdateHistory
407         fields = ('id', 'api', 'event', 'content', 'updater', 'update_time', 'update_status')
408 
409 
410 class YApiEventSerializer(BulkSerializerMixin, serializers.ModelSerializer):
411     """
412     YAPI变更事件信息序列化
413     """
414     update_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
415 
416     class Meta:
417         model = YApiEvent
418         fields = '__all__'
419         list_serializer_class = BulkListSerializer
420 
421 
422 class TestSuiteSerializer(serializers.ModelSerializer):
423     """
424     测试用例集 信息序列化
425     """
426     create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
427     update_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
428     creator = UserSerializer()
429     updater = UserSerializer()
430     labels = GlobalLabelSerializer(many=True, read_only=True)
431     department = DepartmentSerializer()
432 
433     class Meta:
434         model = TestSuite
435         fields = '__all__'
436 
437 
438 class TestSuiteDeserializer(BulkSerializerMixin, serializers.ModelSerializer):
439     """
440     测试用例集 信息序列化
441     """
442 
443     class Meta:
444         model = TestSuite
445         fields = '__all__'
446         list_serializer_class = BulkListSerializer
447 
448 
449 class TestCaseSerializer(serializers.ModelSerializer):
450     """
451     测试用例 信息序列化
452     """
453     create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
454     update_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
455     creator = UserSerializer()
456     updater = UserSerializer()
457     test_suite = TestSuiteSerializer()
458     labels = GlobalLabelSerializer(many=True, read_only=True)
459 
460     class Meta:
461         model = TestCase
462         fields = '__all__'
463 
464 
465 class TestCaseDeserializer(BulkSerializerMixin, serializers.ModelSerializer):
466     """
467     用例信息反序列化
468     """
469     class Meta:
470         model = TestCase
471         fields = '__all__'
472         list_serializer_class = BulkListSerializer
473 
474 
475 class TestStepBaseSerializer(serializers.ModelSerializer):
476     """
477     测试用例步骤 信息序列化
478     """
479     create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
480     update_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
481     creator = UserSerializer()
482     updater = UserSerializer()
483     test_case = TestCaseSerializer()
484     apiInfo = ApiInfoSerializer()
485     labels = GlobalLabelSerializer(many=True, read_only=True)
486 
487     class Meta:
488         model = TestStep
489         fields = '__all__'
490 
491 
492 class TestStepDeserializer(BulkSerializerMixin, serializers.ModelSerializer):
493     """
494     用例步骤信息反序列化
495     """
496     class Meta:
497         model = TestStep
498         fields = '__all__'
499         list_serializer_class = BulkListSerializer
500 
501 
502 class TestStepSerializer(TestStepBaseSerializer):
503     depends = TestStepDeserializer(many=True, read_only=True)
504 
505 
506 class TestReportSerializer(BulkSerializerMixin, serializers.ModelSerializer):
507     """
508     测试结果 信息序列化
509     """
510     create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
511     env = GlobalEnvSerializer()
512 
513     class Meta:
514         model = TestReport
515         fields = '__all__'
516         list_serializer_class = BulkListSerializer
517 
518 
519 class TestReportDeserializer(BulkSerializerMixin, serializers.ModelSerializer):
520     """
521     测试结果 反信息序列化
522     """
523     create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
524 
525     class Meta:
526         model = TestReport
527         fields = '__all__'
528         list_serializer_class = BulkListSerializer
529 
530 
531 class TestTaskSerializer(BulkSerializerMixin, serializers.ModelSerializer):
532     """
533     测试任务 信息序列化
534     """
535     create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
536     test_env = GlobalEnvSerializer()
537     test_validate = GlobalResponseValidateSerializer(read_only=True)
538 
539     class Meta:
540         model = TestTask
541         fields = '__all__'
542         list_serializer_class = BulkListSerializer
543 
544 
545 class TestTaskDeserializer(BulkSerializerMixin, serializers.ModelSerializer):
546     """
547     测试任务 信息序列化
548     """
549     create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
550 
551     class Meta:
552         model = TestTask
553         fields = '__all__'
554         list_serializer_class = BulkListSerializer
555 
556 
557 class TestEnvMonitorSerializer(BulkSerializerMixin, serializers.ModelSerializer):
558     """
559     测试环境验证、状态监控 信息序列化
560     """
561     env = GlobalEnvSerializer()
562     validate = GlobalResponseValidateSerializer()
563     report = TestReportSerializer()
564 
565     class Meta:
566         model = TestEnvMonitor
567         fields = '__all__'
568         list_serializer_class = BulkListSerializer
569 
570 
571 class TestEnvMonitorDeserializer(BulkSerializerMixin, serializers.ModelSerializer):
572     """
573     测试环境验证、状态监控 反信息序列化
574     """
575     class Meta:
576         model = TestEnvMonitor
577         fields = '__all__'
578         list_serializer_class = BulkListSerializer
579 
580 
581 if __name__ == '__main__':
582     pass
View Code

 

三、为每个表数据编写自定义FilterSet,以应付可能需要的复杂过滤查询

  1 #!/usr/bin/python
  2 # -*- coding:utf-8 _*- 
  3 """
  4 @author:TXU
  5 @file:filters.py
  6 @time:2021/09/08
  7 @email:tao.xu2008@outlook.com
  8 @description: 过滤器
  9 """
 10 
 11 import django_filters
 12 from django_filters.rest_framework import FilterSet
 13 from django.utils.translation import gettext_lazy as _
 14 
 15 from apps.api_test.models import Project, ProjectMember, \
 16     GlobalConst, GlobalEnv, GlobalHeader, GlobalLabel, GlobalResponseValidate, \
 17     ApiGroup, ApiInfo, ApiUpdateHistory, YApiEvent, \
 18     TestSuite, TestCase, TestStep, TestReport, TestTask, TestEnvMonitor
 19 
 20 
 21 class BaseAnyInFilter(django_filters.Filter):
 22     """TODO"""
 23     def __init__(self, *args, **kwargs):
 24         kwargs.setdefault('lookup_expr', 'any_in')
 25         kwargs.setdefault('help_text', _('Multiple values may be separated by commas.'))
 26         super().__init__(*args, **kwargs)
 27 
 28         class ConcreteCSVField(self.base_field_class, self.field_class):
 29             pass
 30 
 31         ConcreteCSVField.__name__ = self._field_class_name(
 32             self.field_class, self.lookup_expr
 33         )
 34 
 35         self.field_class = ConcreteCSVField
 36 
 37 
 38 class NumberAnyInFilter(BaseAnyInFilter, django_filters.NumberFilter):
 39     pass
 40 
 41 
 42 class NumberInFilter(django_filters.BaseInFilter, django_filters.NumberFilter):
 43     pass
 44 
 45 
 46 class ProjectFilter(FilterSet):
 47     name = django_filters.CharFilter(field_name='name', lookup_expr='icontains')
 48     id_in = NumberInFilter(field_name='id', lookup_expr='in')
 49     department__isnull = django_filters.CharFilter(field_name='department__id', lookup_expr='isnull')
 50 
 51     class Meta:
 52         model = Project
 53         fields = {
 54             'name': ['icontains'],
 55             'department': ['exact']
 56         }
 57 
 58 
 59 class ProjectMemberFilter(FilterSet):
 60     id_in = NumberInFilter(field_name='id', lookup_expr='in')
 61     user__username = django_filters.CharFilter(field_name='user__username', lookup_expr='icontains')
 62 
 63     class Meta:
 64         model = ProjectMember
 65         fields = {
 66             'project': ['exact'],
 67             'status': ['exact'],
 68             'role': ['exact'],
 69         }
 70 
 71 
 72 class GlobalConstFilter(FilterSet):
 73     id_in = NumberInFilter(field_name='id', lookup_expr='in')
 74 
 75     class Meta:
 76         model = GlobalConst
 77         fields = {
 78             'name': ['exact']
 79         }
 80 
 81 
 82 class GlobalEnvFilter(FilterSet):
 83     id_in = NumberInFilter(field_name='id', lookup_expr='in')
 84     name_icontains = django_filters.CharFilter(field_name='name', lookup_expr='icontains')
 85 
 86     class Meta:
 87         model = GlobalEnv
 88         fields = {
 89             'name': ['exact']
 90         }
 91 
 92 
 93 class GlobalHeaderFilter(FilterSet):
 94     id_in = NumberInFilter(field_name='id', lookup_expr='in')
 95 
 96     class Meta:
 97         model = GlobalHeader
 98         fields = {
 99             'name': ['exact']
100         }
101 
102 
103 class GlobalLabelFilter(FilterSet):
104     id_in = NumberInFilter(field_name='id', lookup_expr='in')
105     status = django_filters.BooleanFilter(field_name='status', lookup_expr='exact')
106 
107     class Meta:
108         model = GlobalLabel
109         fields = {
110             'name': ['exact'],
111             'type': ['exact']
112         }
113 
114 
115 class GlobalResponseValidateFilter(FilterSet):
116     id_in = NumberInFilter(field_name='id', lookup_expr='in')
117 
118     class Meta:
119         model = GlobalResponseValidate
120         fields = {
121             'name': ['exact']
122         }
123 
124 
125 class ApiGroupFilter(FilterSet):
126     id_in = NumberInFilter(field_name='id', lookup_expr='in')
127 
128     class Meta:
129         model = ApiGroup
130         fields = {
131             'name': ['icontains'],
132             'project': ['exact']
133         }
134 
135 
136 class ApiInfoFilter(FilterSet):
137     id_in = NumberInFilter(field_name='id', lookup_expr='in')
138     name_icontains = django_filters.CharFilter(field_name='name', lookup_expr='icontains')
139     path_icontains = django_filters.CharFilter(field_name='path', lookup_expr='icontains')
140     project__isnull = django_filters.Filter(field_name='project', lookup_expr='isnull')
141     api_group__isnull = django_filters.Filter(field_name='api_group', lookup_expr='isnull')
142     project__id__in = NumberInFilter(field_name='project__id', lookup_expr='in')
143     update_status__in = NumberInFilter(field_name='update_status', lookup_expr='in')
144     update_status__gt = django_filters.BooleanFilter(field_name='update_status', lookup_expr='gt')
145     step_api__id__isnull = django_filters.BooleanFilter(field_name='step_api__id', lookup_expr='isnull')
146     create_time__gte = django_filters.DateFilter(field_name='create_time', lookup_expr='gte')
147     create_time__lte = django_filters.DateFilter(field_name='create_time', lookup_expr='lte')
148 
149     class Meta:
150         model = ApiInfo
151         fields = {
152             'name': ['exact'],
153             'path': ['exact'],
154             'project': ['exact'],
155             'api_group': ['exact'],
156             'api_group_id': ['exact'],
157             'update_status': ['exact'],
158         }
159 
160 
161 class ApiUpdateHistoryFilter(FilterSet):
162     id_in = NumberInFilter(field_name='id', lookup_expr='in')
163     api__id__in = NumberInFilter(field_name='api__id', lookup_expr='in')
164     update_status__in = NumberInFilter(field_name='update_status', lookup_expr='in')
165     update_status__gt = django_filters.BooleanFilter(field_name='update_status', lookup_expr='gt')
166 
167     class Meta:
168         model = ApiUpdateHistory
169         fields = {
170             'id': ['icontains'],
171             'api__id': ['exact'],
172             'update_status': ['exact']
173         }
174 
175 
176 class YApiEventFilter(FilterSet):
177     id_in = NumberInFilter(field_name='id', lookup_expr='in')
178 
179     class Meta:
180         model = YApiEvent
181         fields = {
182             'id': ['icontains'],
183             'yapi_id': ['exact'],
184             'event': ['exact']
185         }
186 
187 
188 class TestSuiteFilter(FilterSet):
189     id_in = NumberInFilter(field_name='id', lookup_expr='in')
190     name = django_filters.CharFilter(field_name='name', lookup_expr='icontains')
191     department__in = NumberInFilter(field_name='department__id', lookup_expr='in')
192     department__isnull = django_filters.CharFilter(field_name='department__id', lookup_expr='isnull')
193     labels__in = django_filters.BaseInFilter(field_name='labels', lookup_expr='in')
194 
195     class Meta:
196         model = TestSuite
197         fields = {
198             'id': ['exact'],
199             'name': ['icontains'],
200             'department': ['exact']
201         }
202 
203 
204 class TestCaseFilter(FilterSet):
205     id_in = NumberInFilter(field_name='id', lookup_expr='in')
206     name = django_filters.CharFilter(field_name='name', lookup_expr='icontains')
207     type__in = django_filters.BaseInFilter(field_name='type', lookup_expr='in')
208     result__in = django_filters.BaseInFilter(field_name='result', lookup_expr='in')
209     test_suite__in = NumberInFilter(field_name='test_suite', lookup_expr='in')
210     department__in = NumberInFilter(field_name='test_suite__department__id', lookup_expr='in')
211     label__contains = django_filters.NumberFilter(field_name='labels__id', lookup_expr='contains')
212     labels__name__contains = django_filters.CharFilter(field_name='labels__name', lookup_expr='contains')
213     create_time__gte = django_filters.DateFilter(field_name='create_time', lookup_expr='gte')
214     create_time__lte = django_filters.DateFilter(field_name='create_time', lookup_expr='lte')
215 
216     class Meta:
217         model = TestCase
218         fields = {
219             'id': ['exact'],
220             'name': ['icontains'],
221             'type': ['exact'],
222             'test_suite': ['exact']
223         }
224 
225 
226 class TestStepFilter(FilterSet):
227     name = django_filters.CharFilter(field_name='name', lookup_expr='icontains')
228     description = django_filters.CharFilter(field_name='description', lookup_expr='icontains')
229     id_in = NumberInFilter(field_name='id', lookup_expr='in')
230     result__in = django_filters.BaseInFilter(field_name='result', lookup_expr='in')
231     test_case__in = NumberInFilter(field_name='test_case', lookup_expr='in')
232     apiInfo__in = NumberInFilter(field_name='apiInfo', lookup_expr='in')
233     apiInfo__project__in = NumberInFilter(field_name='apiInfo__project', lookup_expr='in')
234     department__in = NumberInFilter(field_name='test_case__test_suite__department', lookup_expr='in')
235     create_time__gte = django_filters.DateFilter(field_name='create_time', lookup_expr='gte')
236     create_time__lte = django_filters.DateFilter(field_name='create_time', lookup_expr='lte')
237 
238     class Meta:
239         model = TestStep
240         fields = {
241             'id': ['exact'],
242             'name': ['exact'],
243             'description': ['icontains'],
244             'test_case': ['exact'],
245             'apiInfo__id': ['exact'],
246             'apiInfo__project__id': ['exact']
247         }
248 
249 
250 class TestReportFilter(FilterSet):
251     id_in = NumberInFilter(field_name='id', lookup_expr='in')
252     create_time__gte = django_filters.DateTimeFilter(field_name='create_time', lookup_expr='gte')
253     create_time__lte = django_filters.DateTimeFilter(field_name='create_time', lookup_expr='lte')
254 
255     class Meta:
256         model = TestReport
257         fields = {
258             'id': ['exact'],
259             'status': ['exact'],
260             'env': ['exact'],
261             'build_type': ['exact']
262         }
263 
264 
265 class TestTaskFilter(FilterSet):
266     id_in = NumberInFilter(field_name='id', lookup_expr='in')
267     create_time__gte = django_filters.DateTimeFilter(field_name='create_time', lookup_expr='gte')
268     create_time__lte = django_filters.DateTimeFilter(field_name='create_time', lookup_expr='lte')
269 
270     class Meta:
271         model = TestTask
272         fields = {
273             'id': ['exact'],
274             'status': ['exact'],
275         }
276 
277 
278 class TestEnvMonitorFilter(FilterSet):
279     id_in = NumberInFilter(field_name='id', lookup_expr='in')
280     build_type = django_filters.CharFilter(field_name='build_type', lookup_expr='exact')
281     env_name_icontains = django_filters.CharFilter(field_name='env__name', lookup_expr='icontains')
282     create_time__gte = django_filters.DateTimeFilter(field_name='create_time', lookup_expr='gte')
283     create_time__lte = django_filters.DateTimeFilter(field_name='create_time', lookup_expr='lte')
284 
285     class Meta:
286         model = TestEnvMonitor
287         fields = {
288             'id': ['exact'],
289             'status': ['exact'],
290             'build_type': ['exact'],
291         }
292 
293 
294 if __name__ == '__main__':
295     pass
View Code

 

四、ViewSet,实现接口请求

test_suite、test_case、test_step为例:

 1 #!/usr/bin/python
 2 # -*- coding:utf-8 _*- 
 3 """
 4 @author:TXU
 5 @file:test_suite.py
 6 @time:2021/09/01
 7 @email:tao.xu@outlook.com
 8 @description:
 9 """
10 from apps.api_test.view_set.base import ApiTestBaseViewSet, GroupCountModelMixin, TotalCountModelMixin
11 from apps.api_test.models import TestSuite
12 from apps.api_test.serializers import TestSuiteSerializer, TestSuiteDeserializer
13 from apps.api_test.filters import TestSuiteFilter
14 
15 
16 class TestSuiteViewSet(ApiTestBaseViewSet):
17     serializer_class = TestSuiteSerializer
18     queryset = TestSuite.objects.all().order_by('id')
19     filterset_class = TestSuiteFilter
20 
21     # 创建数据
22     def create(self, request, *args, **kwargs):
23         self.serializer_class = TestSuiteDeserializer
24         return super().create(request, *args, **kwargs)
25 
26     # 更新数据
27     def update(self, request, *args, **kwargs):
28         self.serializer_class = TestSuiteDeserializer
29         return super().update(request, *args, **kwargs)
30 
31     # 局部更新数据
32     def partial_update(self, request, *args, **kwargs):
33         self.serializer_class = TestSuiteDeserializer
34         return super().update(request, *args, **kwargs)
35 
36     # 批量 更新数据
37     def bulk_update(self, request, *args, **kwargs):
38         self.serializer_class = TestSuiteDeserializer
39         return super().bulk_update(request, *args, **kwargs)
40 
41     # 批量 局部更新数据
42     def partial_bulk_update(self, request, *args, **kwargs):
43         self.serializer_class = TestSuiteDeserializer
44         return super().partial_bulk_update(request, *args, **kwargs)
45 
46     # 批量 删除数据
47     def bulk_destroy(self, request, *args, **kwargs):
48         self.serializer_class = TestSuiteDeserializer
49         return super().bulk_destroy(request, *args, **kwargs)
50 
51 
52 # 统计数据
53 class TestSuiteTotalViewSet(TotalCountModelMixin):
54     """获取接口总数数据"""
55     filterset_class = TestSuiteFilter
56     queryset = TestSuite.objects.filter(status__exact=True)
57 
58 
59 class TestSuiteCountViewSet(GroupCountModelMixin):
60     """获取测试用例集统计数据"""
61     filterset_class = TestSuiteFilter
62     queryset = TestSuite.objects.filter(status__exact=True)
63     default_group_by_field = 'department'
64     default_time_unit = None
65 
66 
67 if __name__ == '__main__':
68     pass
View Code
 1 #!/usr/bin/python
 2 # -*- coding:utf-8 _*- 
 3 """
 4 @author:TXU
 5 @file:test_case.py
 6 @time:2021/09/01
 7 @email:tao.xu2008@outlook.com
 8 @description:
 9 """
10 from apps.api_test.view_set.base import ApiTestBaseViewSet, GroupCountModelMixin, TotalCountModelMixin
11 from apps.api_test.models import TestCase
12 from apps.api_test.filters import TestCaseFilter
13 from apps.api_test.serializers import TestCaseSerializer, TestCaseDeserializer
14 
15 
16 class TestCaseViewSet(ApiTestBaseViewSet):
17     serializer_class = TestCaseSerializer
18     queryset = TestCase.objects.all().order_by('id')
19     filterset_class = TestCaseFilter
20 
21     # 查询数据
22     def list(self, request, *args, **kwargs):
23         return super().list(request, *args, **kwargs)
24 
25     # 更新数据
26     def update(self, request, *args, **kwargs):
27         self.serializer_class = TestCaseDeserializer
28         return super().update(request, *args, **kwargs)
29 
30     # 局部更新数据
31     def partial_update(self, request, *args, **kwargs):
32         self.serializer_class = TestCaseDeserializer
33         return super().update(request, *args, **kwargs)
34 
35     # 创建数据
36     def create(self, request, *args, **kwargs):
37         self.serializer_class = TestCaseDeserializer
38         return super().create(request, *args, **kwargs)
39 
40     # 批量 更新数据
41     def bulk_update(self, request, *args, **kwargs):
42         self.serializer_class = TestCaseDeserializer
43         return super().bulk_update(request, *args, **kwargs)
44 
45     # 批量 局部更新数据
46     def partial_bulk_update(self, request, *args, **kwargs):
47         self.serializer_class = TestCaseDeserializer
48         return super().partial_bulk_update(request, *args, **kwargs)
49 
50     # 批量 删除数据
51     def bulk_destroy(self, request, *args, **kwargs):
52         self.serializer_class = TestCaseDeserializer
53         return super().bulk_destroy(request, *args, **kwargs)
54 
55 
56 # 统计数据
57 class TestCaseTotalViewSet(TotalCountModelMixin):
58     """获取接口总数数据"""
59     filterset_class = TestCaseFilter
60     queryset = TestCase.objects.filter(status__exact=True)
61 
62 
63 class TestCaseCountViewSet(GroupCountModelMixin):
64     """获取测试用例统计数据"""
65     filterset_class = TestCaseFilter
66     queryset = TestCase.objects.filter(status__exact=True)
67     default_group_by_field = 'type'
68     default_time_unit = None
69 
70 
71 if __name__ == '__main__':
72     pass
View Code
 1 #!/usr/bin/python
 2 # -*- coding:utf-8 _*- 
 3 """
 4 @author:TXU
 5 @file:test_case.py
 6 @time:2021/09/01
 7 @email:tao.xu@outlook.com
 8 @description:
 9 """
10 from apps.api_test.view_set.base import ApiTestBaseViewSet, GroupCountModelMixin, TotalCountModelMixin
11 from apps.api_test.models import TestStep
12 from apps.api_test.filters import TestStepFilter
13 from apps.api_test.serializers import TestStepSerializer, TestStepDeserializer
14 
15 
16 class TestStepViewSet(ApiTestBaseViewSet):
17     serializer_class = TestStepSerializer
18     queryset = TestStep.objects.all().order_by('id')
19     filterset_class = TestStepFilter
20 
21     # 查询数据
22     def list(self, request, *args, **kwargs):
23         return super().list(request, *args, **kwargs)
24 
25     # 更新数据
26     def update(self, request, *args, **kwargs):
27         self.serializer_class = TestStepDeserializer
28         return super().update(request, *args, **kwargs)
29 
30     # 局部更新数据
31     def partial_update(self, request, *args, **kwargs):
32         self.serializer_class = TestStepDeserializer
33         return super().update(request, *args, **kwargs)
34 
35     # 创建数据
36     def create(self, request, *args, **kwargs):
37         self.serializer_class = TestStepDeserializer
38         return super().create(request, *args, **kwargs)
39 
40     # 批量 更新数据
41     def bulk_update(self, request, *args, **kwargs):
42         self.serializer_class = TestStepDeserializer
43         return super().bulk_update(request, *args, **kwargs)
44 
45     # 批量 局部更新数据
46     def partial_bulk_update(self, request, *args, **kwargs):
47         self.serializer_class = TestStepDeserializer
48         return super().partial_bulk_update(request, *args, **kwargs)
49 
50     # 批量 删除数据
51     def bulk_destroy(self, request, *args, **kwargs):
52         self.serializer_class = TestStepDeserializer
53         return super().bulk_destroy(request, *args, **kwargs)
54 
55 
56 # 统计数据
57 class TestStepTotalViewSet(TotalCountModelMixin):
58     """获取接口总数数据"""
59     filterset_class = TestStepFilter
60     queryset = TestStep.objects.filter(status__exact=True)
61 
62 
63 class TestStepCountViewSet(GroupCountModelMixin):
64     """获取测试步骤统计数据"""
65     filterset_class = TestStepFilter
66     queryset = TestStep.objects.filter(status__exact=True)
67     default_group_by_field = 'result'
68     default_time_unit = None
69 
70 
71 if __name__ == '__main__':
72     pass
View Code

 

五、注册路由 urls.py

  1 #!/usr/bin/python
  2 # -*- coding:utf-8 _*- 
  3 """
  4 @author:TXU
  5 @file:urls.py
  6 @time:2021/08/23
  7 @email:tao.xu2008@outlook.com
  8 @description:
  9 """
 10 
 11 from django.conf.urls import url
 12 from django.urls import path, include
 13 # from rest_framework.routers import DefaultRouter
 14 from rest_framework_bulk.routes import BulkRouter
 15 from apps.api_test.view_set.story.department import DepartmentViewSet
 16 from apps.api_test.view_set.story.project import ProjectViewSet
 17 from apps.api_test.view_set.story.project_member import ProjectMemberViewSet
 18 from apps.api_test.view_set.global_config.app_setting import AppSettingViewSet, GetDefaultAppSettingView
 19 from apps.api_test.view_set.global_config.global_env import GlobalEnvViewSet, EnvDataViewSet, \
 20     GetEnvDefaultConfigView, GetEnvDefaultQWExternalContactConfigView
 21 from apps.api_test.view_set.global_config.global_header import GlobalHeaderViewSet
 22 from apps.api_test.view_set.global_config.global_const import GlobalConstViewSet
 23 from apps.api_test.view_set.global_config.global_label import GlobalLabelViewSet
 24 from apps.api_test.view_set.global_config.global_response_validate import GlobalResponseValidateViewSet
 25 from apps.api_test.view_set.api_view.api_info import ApiInfoViewSet, NoCaseApiInfoViewSet, ToDoApiInfoViewSet, \
 26     ApiTotalViewSet, ApiCountViewSet, NoCaseApiCountViewSet, WithCaseApiCountViewSet, ToDoApiCountViewSet
 27 from apps.api_test.view_set.api_view.api_update_history import ApiUpdateHistoryViewSet, \
 28     ApiSyncUpdateStatusToHistoryViewSet
 29 from apps.api_test.view_set.api_view.api_group import ApiGroupViewSet
 30 from apps.api_test.view_set.api_view.yapi_event import YApiEventViewSet
 31 from apps.api_test.view_set.update.yapi import YAPIEventMonitorView, YAPIEventDataSyncView, \
 32     APIDataSyncView, APICaseTemplateUpdateView
 33 from apps.api_test.view_set.test_view.test_suite import TestSuiteViewSet, TestSuiteCountViewSet, TestSuiteTotalViewSet
 34 from apps.api_test.view_set.test_view.test_case import TestCaseViewSet, TestCaseCountViewSet, TestCaseTotalViewSet
 35 from apps.api_test.view_set.test_view.test_step import TestStepViewSet, TestStepCountViewSet, TestStepTotalViewSet
 36 from apps.api_test.view_set.test_view.test_report import TestReportViewSet, PytestHtmlViewSet, JenkinsAllureViewSet, \
 37     TestLogsViewSet
 38 from apps.api_test.view_set.test_view.test_env_monitor import TestEnvMonitorViewSet
 39 from apps.api_test.view_set.task.test_task import TestTaskViewSet
 40 from apps.api_test.view_set.upload.case_upload import UploadFileView
 41 
 42 from apps.api_test.view_set.help.comparators import ComparatorHelpViewSet
 43 from apps.api_test.view_set.help.functions import BuiltinFunctionHelpViewSet, CustomizedCallBackFunctionHelpViewSet, \
 44     CustomizedMallFunctionHelpViewSet, CustomizedSettingsFunctionHelpViewSet
 45 
 46 from apps.api_test.view_set.runner.run import TestRunViewSet
 47 
 48 # router = DefaultRouter()
 49 router = BulkRouter()
 50 
 51 # department
 52 router.register(r'department/bulk', DepartmentViewSet),  # 批量处理
 53 router.register(r'department/list', DepartmentViewSet, basename='list'),
 54 router.register(r'department/detail', DepartmentViewSet, basename='retrieve'),
 55 router.register(r'department/add', DepartmentViewSet, basename='create'),
 56 router.register(r'department/update', DepartmentViewSet, basename='update'),
 57 router.register(r'department/del', DepartmentViewSet, basename='destroy')
 58 
 59 # project
 60 router.register(r'project/bulk', ProjectViewSet),  # 批量处理
 61 router.register(r'project/list', ProjectViewSet, basename='list'),
 62 router.register(r'project/detail', ProjectViewSet, basename='retrieve'),
 63 router.register(r'project/add', ProjectViewSet, basename='create'),
 64 router.register(r'project/update', ProjectViewSet, basename='update'),
 65 router.register(r'project/del', ProjectViewSet, basename='destroy')
 66 
 67 # project member
 68 router.register(r'project/member/list', ProjectMemberViewSet, basename='list'),
 69 router.register(r'project/member/detail', ProjectMemberViewSet, basename='retrieve'),
 70 router.register(r'project/member/add', ProjectMemberViewSet, basename='create'),
 71 router.register(r'project/member/update', ProjectMemberViewSet, basename='update'),
 72 router.register(r'project/member/del', ProjectMemberViewSet, basename='destroy')
 73 
 74 # app系统配置
 75 router.register(r'global/app_setting/list', AppSettingViewSet, basename='list'),
 76 router.register(r'global/app_setting/detail', AppSettingViewSet, basename='retrieve'),
 77 router.register(r'global/app_setting/add', AppSettingViewSet, basename='create'),
 78 router.register(r'global/app_setting/update', AppSettingViewSet, basename='update'),
 79 router.register(r'global/app_setting/del', AppSettingViewSet, basename='destroy'),
 80 router.register(r'global/app_setting/data', GetDefaultAppSettingView, basename='retrieve'),
 81 
 82 # global env 环境配置
 83 router.register(r'global/env/bulk', GlobalEnvViewSet),
 84 router.register(r'global/env/list', GlobalEnvViewSet, basename='list'),
 85 router.register(r'global/env/detail', GlobalEnvViewSet, basename='retrieve'),
 86 router.register(r'global/env/add', GlobalEnvViewSet, basename='create'),
 87 router.register(r'global/env/update', GlobalEnvViewSet, basename='update'),
 88 router.register(r'global/env/del', GlobalEnvViewSet, basename='destroy'),
 89 router.register(r'global/env/data', EnvDataViewSet, basename='retrieve'),
 90 
 91 # global header
 92 router.register(r'global/header/bulk', GlobalHeaderViewSet),
 93 router.register(r'global/header/list', GlobalHeaderViewSet, basename='list'),
 94 router.register(r'global/header/detail', GlobalHeaderViewSet, basename='retrieve'),
 95 router.register(r'global/header/add', GlobalHeaderViewSet, basename='create'),
 96 router.register(r'global/header/update', GlobalHeaderViewSet, basename='update'),
 97 router.register(r'global/header/del', GlobalHeaderViewSet, basename='destroy'),
 98 
 99 # global const
100 router.register(r'global/const/bulk', GlobalConstViewSet),
101 router.register(r'global/const/list', GlobalConstViewSet, basename='list'),
102 router.register(r'global/const/detail', GlobalConstViewSet, basename='retrieve'),
103 router.register(r'global/const/add', GlobalConstViewSet, basename='create'),
104 router.register(r'global/const/update', GlobalConstViewSet, basename='update'),
105 router.register(r'global/const/del', GlobalConstViewSet, basename='destroy'),
106 
107 # global label
108 router.register(r'global/label/bulk', GlobalLabelViewSet),
109 router.register(r'global/label/list', GlobalLabelViewSet, basename='list'),
110 router.register(r'global/label/detail', GlobalLabelViewSet, basename='retrieve'),
111 router.register(r'global/label/add', GlobalLabelViewSet, basename='create'),
112 router.register(r'global/label/update', GlobalLabelViewSet, basename='update'),
113 router.register(r'global/label/del', GlobalLabelViewSet, basename='destroy'),
114 
115 # global response_validate
116 router.register(r'global/response_validate/bulk', GlobalResponseValidateViewSet),
117 router.register(r'global/response_validate/list', GlobalResponseValidateViewSet, basename='list'),
118 router.register(r'global/response_validate/detail', GlobalResponseValidateViewSet, basename='retrieve'),
119 router.register(r'global/response_validate/add', GlobalResponseValidateViewSet, basename='create'),
120 router.register(r'global/response_validate/update', GlobalResponseValidateViewSet, basename='update'),
121 router.register(r'global/response_validate/del', GlobalResponseValidateViewSet, basename='destroy'),
122 
123 # api group
124 router.register(r'api/group/bulk', ApiGroupViewSet),
125 router.register(r'api/group/list', ApiGroupViewSet, basename='list'),
126 router.register(r'api/group/detail', ApiGroupViewSet, basename='retrieve'),
127 router.register(r'api/group/add', ApiGroupViewSet, basename='create'),
128 router.register(r'api/group/update', ApiGroupViewSet, basename='update'),
129 router.register(r'api/group/del', ApiGroupViewSet, basename='destroy'),
130 
131 # api info
132 router.register(r'api/bulk', ApiInfoViewSet),
133 router.register(r'api/list', ApiInfoViewSet, basename='list'),
134 router.register(r'api/nocase/list', NoCaseApiInfoViewSet, basename='no_case_list'),
135 router.register(r'api/todo/list', ToDoApiInfoViewSet, basename='todo_list'),
136 router.register(r'api/detail', ApiInfoViewSet, basename='retrieve'),
137 router.register(r'api/add', ApiInfoViewSet, basename='create'),
138 router.register(r'api/update', ApiInfoViewSet, basename='update'),
139 router.register(r'api/del', ApiInfoViewSet, basename='destroy'),
140 router.register(r'api/total', ApiTotalViewSet, basename='list'),
141 router.register(r'api/count', ApiCountViewSet, basename='list'),
142 router.register(r'api/count/no_case', NoCaseApiCountViewSet, basename='list'),
143 router.register(r'api/count/with_case', WithCaseApiCountViewSet, basename='list'),
144 router.register(r'api/count/todo', ToDoApiCountViewSet, basename='list'),
145 
146 # api update history
147 router.register(r'api/update_history/list', ApiUpdateHistoryViewSet, basename='list'),
148 router.register(r'api/update_history/detail', ApiUpdateHistoryViewSet, basename='retrieve'),
149 router.register(r'api/update_history/add', ApiUpdateHistoryViewSet, basename='create'),
150 router.register(r'api/update_history/update', ApiUpdateHistoryViewSet, basename='update'),
151 router.register(r'api/update_history/del', ApiUpdateHistoryViewSet, basename='destroy'),
152 
153 # yapi event
154 router.register(r'api/yapi_event/bulk', YApiEventViewSet),
155 router.register(r'api/yapi_event/list', YApiEventViewSet, basename='list'),
156 router.register(r'api/yapi_event/detail', YApiEventViewSet, basename='retrieve'),
157 # router.register(r'api/yapi_event/add', YApiEventViewSet, basename='create'),  # YAPIEventMonitorView 调用
158 router.register(r'api/yapi_event/update', YApiEventViewSet, basename='update'),
159 router.register(r'api/yapi_event/del', YApiEventViewSet, basename='destroy'),
160 
161 # test suite
162 router.register(r'test/suite/bulk', TestSuiteViewSet),  # 批量处理
163 router.register(r'test/suite/list', TestSuiteViewSet, basename='list'),
164 router.register(r'test/suite/detail', TestSuiteViewSet, basename='detail'),
165 router.register(r'test/suite/add', TestSuiteViewSet, basename='create'),
166 router.register(r'test/suite/update', TestSuiteViewSet, basename='update'),
167 router.register(r'test/suite/del', TestSuiteViewSet, basename='destroy'),
168 router.register(r'test/suite/total', TestSuiteTotalViewSet, basename='list'),
169 router.register(r'test/suite/count', TestSuiteCountViewSet, basename='list'),
170 
171 # test case
172 router.register(r'test/case/bulk', TestCaseViewSet),  # 批量处理
173 router.register(r'test/case/list', TestCaseViewSet, basename='list'),
174 router.register(r'test/case/detail', TestCaseViewSet, basename='retrieve'),
175 router.register(r'test/case/add', TestCaseViewSet, basename='create'),
176 router.register(r'test/case/update', TestCaseViewSet, basename='update'),
177 router.register(r'test/case/del', TestCaseViewSet, basename='destroy'),
178 router.register(r'test/case/total', TestCaseTotalViewSet, basename='list'),
179 router.register(r'test/case/count', TestCaseCountViewSet, basename='list'),
180 
181 # test step
182 router.register(r'test/step/bulk', TestStepViewSet),  # 批量处理
183 router.register(r'test/step/list', TestStepViewSet, basename='list'),
184 router.register(r'test/step/detail', TestStepViewSet, basename='retrieve'),
185 router.register(r'test/step/add', TestStepViewSet, basename='create'),
186 router.register(r'test/step/update', TestStepViewSet, basename='update'),
187 router.register(r'test/step/del', TestStepViewSet, basename='destroy'),
188 router.register(r'test/step/total', TestStepTotalViewSet, basename='list'),
189 router.register(r'test/step/count', TestStepCountViewSet, basename='list'),
190 
191 # 测试执行
192 router.register(r'test/run', TestRunViewSet, basename='create'),
193 
194 # 测试报告
195 router.register(r'test/report/bulk', TestReportViewSet),  # 批量处理
196 router.register(r'test/report/list', TestReportViewSet, basename='list'),
197 router.register(r'test/report/detail', TestReportViewSet, basename='retrieve'),
198 router.register(r'test/report/update', TestReportViewSet, basename='update'),
199 router.register(r'test/report/pytest_html', PytestHtmlViewSet, basename='retrieve'),
200 router.register(r'test/report/jenkins_allure', JenkinsAllureViewSet, basename='retrieve'),
201 router.register(r'test/report/logs', TestLogsViewSet, basename='retrieve'),
202 
203 # 测试环境验证、状态监控
204 router.register(r'test/env_monitor/bulk', TestEnvMonitorViewSet),  # 批量处理
205 router.register(r'test/env_monitor/list', TestEnvMonitorViewSet, basename='list'),
206 router.register(r'test/env_monitor/detail', TestEnvMonitorViewSet, basename='retrieve'),
207 router.register(r'test/env_monitor/add', TestEnvMonitorViewSet, basename='create'),
208 router.register(r'test/env_monitor/update', TestEnvMonitorViewSet, basename='update'),
209 router.register(r'test/env_monitor/del', TestEnvMonitorViewSet, basename='destroy'),
210 
211 # 测试任务
212 # router.register(r'test/task/bulk', TestTaskViewSet),  # 批量处理 - 暂不支持
213 router.register(r'test/task/add', TestTaskViewSet, basename='create'),
214 router.register(r'test/task/update', TestTaskViewSet, basename='update'),
215 router.register(r'test/task/del', TestTaskViewSet, basename='destroy'),
216 router.register(r'test/task/list', TestTaskViewSet, basename='list'),
217 router.register(r'test/task/detail', TestTaskViewSet, basename='retrieve'),
218 
219 # 帮助信息
220 router.register(r'help/comparator/list', ComparatorHelpViewSet, basename='list'),
221 router.register(r'help/builtin_functions/list', BuiltinFunctionHelpViewSet, basename='list')
222 router.register(r'help/callback_functions/list', CustomizedCallBackFunctionHelpViewSet, basename='list')
223 router.register(r'help/mall_functions/list', CustomizedMallFunctionHelpViewSet, basename='list')
224 router.register(r'help/settings_functions/list', CustomizedSettingsFunctionHelpViewSet, basename='list')
225 
226 urlpatterns = [
227     # path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
228 
229     # 数据表管理
230     path('', include(router.urls)),
231 
232     # file xmind
233     url(r"file/upload", UploadFileView.as_view()),
234     # 获取env默认数据
235     url(r'global/env/config/default', GetEnvDefaultConfigView.as_view()),
236     url(r'global/env/qw_external_contact_config/default', GetEnvDefaultQWExternalContactConfigView.as_view()),
237     # YAPI事件监听
238     url(r'api/yapi_event/add', YAPIEventMonitorView.as_view()),
239     # YAPI事件数据同步到本地接口
240     url(r'api/yapi_event/data_sync', YAPIEventDataSyncView.as_view()),
241     # 本地接口拉取YAPI数据同步
242     url(r'api/data_sync', APIDataSyncView.as_view()),
243     # 本地接口用例模板更新
244     url(r'api/update/case_template', APICaseTemplateUpdateView.as_view()),
245     # 接口update_status同步到接口变更历史表
246     url(r'api/sync/update_history/update_status', ApiSyncUpdateStatusToHistoryViewSet.as_view()),
247 ]
248 
249 
250 if __name__ == '__main__':
251     pass
View Code

 

 

 

-------- THE END --------

rest_framework_bulk
posted @ 2021-12-04 17:44  徒手沉浮  阅读(753)  评论(0编辑  收藏  举报