接口开发、多进程--18

1、注册接口

1)views.py

 1 class RegisterView(BaseView, PostView):
 2     '''注册需要md5加密在写入到数据库中'''
 3     model_class = models.User  # 用哪个model类
 4     form_class = forms.RegisterForm  # 用哪个form类
 5 
 6     def post(self, request):
 7         form_obj = self.form(request.POST)
 8         if form_obj.is_valid():
 9             # print(form_obj.cleaned_data)
10             # md5加密
11             md5_password = self.model.make_password(form_obj.cleaned_data['password'])
12             # 更新原有的cleaned_data
13             form_obj.cleaned_data['password'] = md5_password
14             # 再创建
15             # print(form_obj.cleaned_data)
16             self.model.objects.create(**form_obj.cleaned_data)
17             ret = NbResponse()  # 默认请求成功
18         else:
19             ret = NbResponse(code=-1, msg=form_obj.error_format)
20         return ret
2)forms.py
1 # 注册的form验证
2 class RegisterForm(ModelForm, ExtendForm):
3     class Meta:
4         model = models.User
5         exclude = ['is_delete']
3)urls.py
path('register', views.RegisterView.as_view()),

2、项目管理接口

  • 重点:重构
  • 将用户名返回显示在创建人,实际数据库中外键自关联是根据user_id,需要重构
  • 因为接口是get请求,所以我们重构get方法,路径 NbView--GetView,复制get方法后修改
  • 接口文档查看接口返回内容:

 

 (1)views.py

 1 class ProjectView(NbView):
 2     search_field = ["name"]  # 根据哪些字段来搜索
 3     filter_field = []  # 根据哪些字段来搜索
 4     model_class = models.Project  # 用哪个model类
 5     form_class = forms.ProjectForm  # 用哪个form类
 6     # 重构内容,将get方法复制修改下
 7     def get(self, request):
 8         page_data, page_obj = self.get_query_set_page_data()  # 获取分页之后的数据
 9         data_list = []
10         for instance in page_data:  
11             model_dict = model_to_dict(instance, self.fields, self.exclude_fields)  # 转成字典
12             # 外键关联user表,将username返回给user
13             model_dict['user'] = instance.user.username
14             data_list.append(model_dict)
15         return NbResponse(data=data_list, count=page_obj.count)

 

(2)forms.py

class ProjectForm(ModelForm,ExtendForm):
    '''项目表'''
    class Meta:
        model = models.Project
        exclude = ['is_delete']

(3)urls.py配置路径
1 path('project', views.ProjectView.as_view()),#项目

3、接口管理接口

同项目接口一样都是get请求,需要重构get方法

接口管理接口设计的返回值

 

(1)、views.py

 1 class InterfaceView(NbView):
 2     search_field = ["name"]  # 根据哪些字段来搜索
 3     filter_field = ['project']  # 根据哪些字段来搜索
 4     model_class = models.Interface  # 用哪个model类
 5     form_class = forms.InterfaceForm  # 用哪个form类
 6 
 7     def get(self, request):
 8         page_data, page_obj = self.get_query_set_page_data()  # 获取分页之后的数据
 9         data_list = []
10         for instance in page_data:  #
11             model_dict = model_to_dict(instance, self.fields, self.exclude_fields)  # 转成字典
12             model_dict['user'] = instance.user.username
13             model_dict['project_name'] = instance.project.name
14             model_dict['project_id'] = instance.project.id
15             data_list.append(model_dict)
16         return NbResponse(data=data_list, count=page_obj.count)

(2)、forms.py

1 class InterfaceForm(ModelForm,ExtendForm):
2     '''接口表'''
3     class Meta:
4         model = models.Interface
5         exclude = ['is_delete']
(3)、urls.py
1 path('interface', views.InterfaceView.as_view()),#接口

4、用例管理接口

 (1)、views.py

 1 from sksystem.core.case_utils import get_premise_case,check_premise
 2 class CaseView(NbView):
 3     search_field = ["title"]  # 根据哪些字段来搜索
 4     filter_field = ['project']  # 根据哪些字段来搜索
 5     model_class = models.Case  # 用哪个model类
 6     form_class = forms.CaseForm  # 用哪个form类
 7 
 8     def get(self, request):
 9         page_data, page_obj = self.get_query_set_page_data()  # 获取分页之后的数据
10         data_list = []
11         for instance in page_data:  #
12             model_dict = model_to_dict(instance, self.fields, self.exclude_fields)  # 转成字典
13             model_dict['user'] = instance.user.username
14             model_dict['project_name'] = instance.project.name
15             model_dict['project_id'] = instance.project.id
16             model_dict['interface_name'] = instance.interface.name
17             model_dict['interface_id'] = instance.interface.id
18             model_dict['rely_case'] = get_premise_case(instance)#编辑的时候需要带出已经依赖的用例
19             data_list.append(model_dict)
20         return NbResponse(data=data_list, count=page_obj.count)
21 
22 # 添加用例的时候选择依赖的用例,但是没有创建自关联的关系,添加保存的时候走的是post方法,走的是NbView默认post方法
23 # 由于需要创建依赖用例的自关联,所以需要重写post
24 def post(self, request):
25     form_obj = self.form(request.POST)
26     # 从request.POST将用例依赖的case取出来
27     rely_case = request.POST.get('rely_case')
28     if form_obj.is_valid():
29         # 想要进行自关联绑定,需要具备依赖用用例的id、以及自己的id 就是case.id
30         case = self.model.objects.create(**form_obj.cleaned_data)
31         # 绑定自关联 创建自关联关系
32         for rely_case_id in json.loads(rely_case):#rely_case实际上是字符串,json.loads()转化成数组
33             models.CasePremise.objects.create(case_id=case.id, premise_case_id=rely_case_id)#创建关系
34         ret = NbResponse()  # 默认请求成功
35     else:
36         ret = NbResponse(code=-1, msg=form_obj.error_format)
37     return ret
38 def put(self, request):
39     #  用例在更新时处理自关联的关系。
40     # 先清掉之前所有的关联,然后在重新创建
41     #外键子自关联
42     rely_case = request.PUT.get('rely_case')
43     instance = self.model.objects.get(id=request.PUT.get('id'))
44     form_obj = self.form(request.PUT, instance=instance)
45     print('form_obj的返回数据:', form_obj)  # 添加的用例的全部信息
46     if form_obj.is_valid():
47         # 通过当前用例 获取所有被依赖的用例 并删除
48         instance.case.all().delete()
49         # 重新建立自关联绑定关系
50         for item in json.loads(rely_case):
51             models.CasePremise.objects.create(case_id=instance.id, premise_case_id=item)
52         form_obj.save()
53         ret = NbResponse()  # 默认请求成功
54     else:
55         ret = NbResponse(code=-1, msg=form_obj.error_format)
56     return ret

 

注意:单独新建了一个文件,然后将方法写在这个文件中/core/case_utils.py
********
方法:外键自关联

"rely_case": [

{
  "id": 4,
  "title": "用例数据3"
}, ]

 1 from sksystem import models
 2 
 3 
 4 def get_premise_case(instance):
 5     qs = instance.case.all()#知道当前的case的依赖用例,返回的是列表
 6     rely_cases = []
 7     for item in qs:
 8         rely_cases.append({"id": item.premise_case.id, "title": item.premise_case.title})
 9     print(rely_cases)
10     return rely_cases
*********
添加用例的时候选择项目,需要返回当前项目下所有的用例
# 由于添加用例时,需要根据项目获取所有用例。因此开发/api/get_rely_case
 1 class RelyCaseView(View):
 2     '''GET /api/get_rely_case?project_id=4 HT  如果不带case_id 说明是添加,只需要将项目下的用例返回
 3     /api/get_rely_case?project_id=4&case_id=7   # 如果带了caseid 说明是编辑,需要将这个case的依赖返回。
 4     1、项目下还没有用例   直接返回
 5     2、项目下已经有用例
 6         {
 7             "code": 0,
 8             "msg": "操作成功",
 9             "data": [
10                 {
11                     "id": 2,
12                     "title": "测试平台项目接口"
13                 },
14                 {
15                     "id": 1,
16                     "title": "测试平台登录接口"
17                 }
18             ]
19         }
20     '''
21 
22     def get(self, requests):
23         project_id = requests.GET.get('project_id')
24         case_id = requests.GET.get('case_id')
25         if case_id:
26             # 编辑操作 当前这条用例不可以返回  通过exclude 进行过滤,返回的数据不包括已经被删除的用例
27             qs_data = models.Case.objects.filter(project_id=project_id, is_delete=1).exclude(id=case_id).values('id',
28                                                                                                                 'title')
29         else:#如果当前项目下没有用例,直接返回,当前项目下有用例,返回用例的id和title
30             qs_data = models.Case.objects.filter(project_id=project_id, is_delete=1).values('id', 'title')
31         return NbResponse(data=list(qs_data))

(2)、forms.py
1 class CaseForm(ModelForm, ExtendForm):
2     class Meta:
3         model = models.Case
4         exclude = ['is_delete', 'status']
(3)urls.py
path('case', views.CaseView.as_view()),
path('get_rely_case', views.RelyCaseView.as_view()),

5、用例集合管理

 

(1)views.py
class CaseCollectionView(NbView):
    search_field = ["name"]  # 根据哪些字段来搜索
    filter_field = ['project']  # 根据哪些字段来搜索
    model_class = models.CaseCollection  # 用哪个model类
    form_class = forms.CaseCollectionFrom  # 用哪个form类
    exclude_fields = ['is_delete', 'case']  # 返回的时候排除哪些字段
#和case存在多对多关系
    # 查询多对多
    # 正向 根据集合查集合下的用例
    # print(coll_obj.case.all())
    # # 反向 根据用例查所在集合
    # print(case_obj_A.casecollection_set.all())
    def get(self, request):
        page_data, page_obj = self.get_query_set_page_data()  # 获取分页之后的数据
        data_list = []
        for instance in page_data:  #
            model_dict = model_to_dict(instance, self.fields, self.exclude_fields)  # 转成字典
            model_dict['user'] = instance.user.username
            model_dict['project_name'] = instance.project.name
            model_dict['project_id'] = instance.project.id
            model_dict['case_count'] = instance.case.all().count()#用例数 查询多对多,正向查询--根据集合查几个下所有的用例
            data_list.append(model_dict)
        return NbResponse(data=data_list, count=page_obj.count)
(2)forms.py
1 class CaseCollectionFrom(ModelForm, ExtendForm):
2     class Meta:
3         model = models.CaseCollection
4         exclude = ['is_delete', 'status','case']
(3)urls.py
1 path('case_collection', views.CaseCollectionView.as_view()),

5、加入用例接口--集合中添加用例时需要调用join_case 接口

 (1)views.py

 1 # 根据 项目和集合id 获取要选择的用例
 2 class JoinCaseView(View):
 3     def get(self, request):
 4         '''
 5         #http://127.0.0.1:8000/api/join_case?project_id=6&id=3
 6 {
 7     "code": 0,
 8     "msg": "操作成功",
 9     "data": {
10         "all_case": [
11             {
12                 "id": 2,
13                 "title": "测试平台项目接口"
14             },
15             {
16                 "id": 1,
17                 "title": "测试平台登录接口"
18             }
19         ],
20         "join_case": [
21             2,
22             1
23         ]
24     }
25 }
26 
27         :param request:
28         :return:
29 
30         1、根据项目id 返回当前项目下所有没有被删除的用例。
31         2、根据集合id 获取已经和集合创建关系的用例id。
32         '''
33         project_id = request.GET.get('project_id')  # 项目id
34         coll_id = request.GET.get('id')  # 集合id
35         all_case = models.Case.objects.filter(project_id=project_id, is_delete=1).values('id', 'title')#根据项目id获取到当前项目下所有没有被删除的用例
36         # 获取集合
37         coll_obj = models.CaseCollection.objects.get(id=coll_id)
38         # 通过多对多的查询获取集合下的用例 只要id字段
39         join_case_qs = coll_obj.case.all().values('id')
40         join_case = []  # 具体返回的joincase
41         for item in join_case_qs:
42             join_case.append(item.get('id'))
43         data = {
44             "all_case": list(all_case),
45             "join_case": join_case
46         }
47         return NbResponse(data=data)
48 
49     def post(self, request):
50         # http://127.0.0.1:8000/api/join_case
51         '''
52         join_case_list: [11,9,8,7]
53         id: 3
54 
55 
56         :param request:
57         :return:
58         '''
59         join_case_list = request.POST.get('join_case_list')
60         coll_id = request.POST.get('id')
61         coll_obj = models.CaseCollection.objects.get(id=coll_id)
62         # # 更新时第一种方案  清掉之前绑定的数据
63         # coll_obj.case.clear()
64         # for item in json.loads(join_case_list):
65         #     coll_obj.case.add(item)
66         # 第二种方案  通过 set的方式进行创建和更新
67         coll_obj.case.set(json.loads(join_case_list))
68         return NbResponse()

 

 (2)urls.py

path('join_case', views.JoinCaseView.as_view()),

6、异步任务:

  • 同步:用例运行,点击运行后,一直等待结果返回
  • 异步:用例运行,点击运行后,返回信息:‘用例已经运行’,等会回来看结果就可以了
  • pip install Celery

 

 1、config.py中配置自己的redis

2、main.py 不用动,写好的

 

 3、task.py

例子:简单的实现下异步任务:

1)、tasks.py

 1 from celery.utils.log import get_task_logger
 2 from celery_tasks.main import app #导入main.py中声明的app
 3 
 4 logger = get_task_logger('django_server')
 5 
 6 @app.task(name='run_caseymy')
 7 def run_case(case_id,user_id):
 8     import time
 9     time.sleep(10)
10     print(case_id)
11     print(user_id)

 

启动celery 的服务

# mac同学
# celery -A celery_tasks.main worker -l info 普通启动
# celery multi start w1 -A celery_tasks.main -l info --logfile=logs/celerylog.log --pidfile=logs/celerypid.pid 后台运行
# celery flower -A celery_tasks.main 打开一个web页面启动 需要提前安装下flow 安装命令:pip install flower

# win同学
# pip install eventlet
# celery -A celery_tasks.main worker -l info -P eventlet

 2)、app目录下的tests.py

 3)运行:

先执行tests.py 执行后效果如图:

 

 tasks.py会自动执行,效果如图:

 

 7、运行操作:

1、urls.py

1 path('run', views.CaseRunView.as_view()),

2、view.py

1 class CaseRunView(View):
2     def post(self, request):
3         case_id = request.POST.get('case_id')#用例id
4         user_id = request.POST.get('user_id')
5         task_id = run_case.delay(case_id,user_id)
6         print(task_id)
7 
8          return NbResponse()

3、tasks.py

 1 from celery.utils.log import get_task_logger
 2 from celery_tasks.main import app #导入main.py中声明的app
 3 import time
 4 logger = get_task_logger('django_server')
 5 #用例运行
 6 @app.task(name='run_caseymy')
 7 def run_case(case_id,user_id):
 8     task_id = run_case.request.id
 9     print('task:id',task_id)
10     time.sleep(10)
11     print(case_id)
12     print(user_id)

重启celery服务:
celery -A celery_tasks.main worker -l info -P eventlet
重启项目:
效果:用例处点击运行按钮后,返回的task_id 可以对上

 

 

 

 

 

完善views.py后

 1 class CaseRunView(View):
 2     def post(self, request):
 3         case_id = request.POST.get('case_id')#用例id
 4         user_id = request.POST.get('user_id')
 5 
 6 
 7         for item_id in json.loads(case_id):
 8             # 当页面调用异步任务时,会返回一个唯一的任务id
 9             task_id = run_case.delay(item_id, request.user.id)
10             print('当前用例的task_id',task_id)
11             models.Case.objects.filter(id=item_id).update(report_batch=task_id, status=3)#修改用例状态,3是运行中的状态
12         return NbResponse()
页面再次点击运行

 

 

 

 

 

 

 

 

 8、集合运行

1、urls.py

path('run_collection', views.CollectionRunView.as_view()),

2、views.py

 1 class CollectionRunView(View):
 2     def post(self, request):
 3         collect_id = request.POST.get('collect_id')#集合id
 4         user_id = request.POST.get('user_id')
 5         for item_id in json.loads(collect_id):
 6             # 当页面调用异步任务时,会返回一个唯一的任务id
 7             task_id = run_collection.delay(item_id, request.user.id)
 8             print('集合的task_id',task_id)
 9             models.CaseCollection.objects.filter(id=item_id).update(report_batch=task_id, status=3)#修改用例状态,3是运行中的状态
10         return NbResponse()
3、tasks.py
1 #集合运行
2 @app.task(name='run_collect')
3 def run_collection(collect_id, user_id):
4     task_id = run_collection.request.id
5     print('集合task:id', task_id)
6     time.sleep(10)
7     print(collect_id)
8     print(user_id)    
后台点击运行后,集合状态更改成运行中

posted @ 2020-02-27 12:58  洛歆陌离  阅读(183)  评论(0编辑  收藏  举报