Просмотр исходного кода

添加测试计划关联以及版本关联分析(本地测试通过)

刘凡 1 год назад
Родитель
Сommit
5559ff545f

+ 1 - 1
Dockerfile

@@ -1,4 +1,4 @@
-From python:3.9
+FROM python:3.9
 
 MAINTAINER Liufan<1649750212@qq.com>
 ENV PYTHONUNBUFFERED 1

+ 0 - 0
apps/plan/dao/__init__.py


+ 0 - 0
apps/plan/dao/plandao.py


+ 18 - 0
apps/plan/migrations/0003_testplan_type.py

@@ -0,0 +1,18 @@
+# Generated by Django 3.2.4 on 2023-02-01 11:14
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('plan', '0002_alter_testplan_id'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='testplan',
+            name='type',
+            field=models.CharField(max_length=30, null=True, verbose_name='测试计划类型'),
+        ),
+    ]

+ 1 - 5
apps/plan/models.py

@@ -1,19 +1,15 @@
-import os
-
 from django.db import models
 
 # Create your models here.
-from TestLaboratory.settings import PLAN_ROOT
-from apps.file.models import FileManager
 from apps.software.models import Software
 from apps.user.models import User
-from utils.util_add_id import gen_next_id
 
 
 class TestPlan(models.Model):
     id = models.CharField(max_length=128, unique=True, primary_key=True, verbose_name='测试计划编号',
                           default='TestLaboratory_V1_Plan_1')
     title = models.CharField(max_length=30, verbose_name='测试计划标题')
+    type = models.CharField(max_length=30, verbose_name='测试计划类型', null=True)
     software = models.ForeignKey(Software, on_delete=models.CASCADE, verbose_name='测试软件')
     version = models.CharField(max_length=20, verbose_name='软件版本')
     creator = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, verbose_name='测试计划执行者')

+ 3 - 2
apps/plan/urls.py

@@ -1,9 +1,10 @@
 from django.urls import path
 from .views.planlistview import PlanListView
-from .views.planview import PlanView, PlanEdit
+from .views.planview import PlanView, PlanEdit, PlanEditType
 
 urlpatterns = [
     path('', PlanListView.as_view()),
     path('<str:plan_id>', PlanView.as_view()),
-    path('<str:plan_id>/edit', PlanEdit.as_view())
+    path('<str:plan_id>/edit', PlanEdit.as_view()),
+    path('<str:plan_id>/edit-type', PlanEditType.as_view())
 ]

+ 6 - 5
apps/plan/views/planlistview.py

@@ -1,11 +1,12 @@
 import datetime
-import json
+import logging
 import os
 
+from django.http import HttpResponse
 from rest_framework.response import Response
 from rest_framework.views import APIView
-from django.http import HttpResponse
 
+from TestLaboratory.settings import PLAN_ROOT
 from apps.file.models import FileManager
 from apps.log.models import get_log, gen_log
 from apps.plan.models import TestPlan
@@ -13,9 +14,7 @@ from apps.software.models import Software
 from apps.user.middleware.rolecontrol import RoleControl
 from apps.user.models import User
 from utils.util_add_id import gen_next_id, get_id
-from TestLaboratory.settings import PLAN_ROOT
 
-import logging
 logger = logging.getLogger('django')
 
 
@@ -30,6 +29,7 @@ class PlanListView(APIView):
         software_id = request.POST.get('software_id')
         version_number = request.POST.get('version_number')
         title = request.POST.get('title')
+        plan_type = request.POST.get('type')
         description = request.POST.get('description')
         files = request.FILES.getlist('files')
         creator_id = request.POST.get('creator')
@@ -97,7 +97,7 @@ class PlanListView(APIView):
         fids = fids[:-2]
 
         try:
-            plan = TestPlan.objects.create(id=id_plan, title=title, description=description, state='0',
+            plan = TestPlan.objects.create(id=id_plan, title=title, description=description, state='0', type=plan_type,
                                            creator=creator, software=software, version=software_version.number,
                                            statement_file=fids,
                                            create_time=create_time, update_time=update_time)
@@ -115,6 +115,7 @@ class PlanListView(APIView):
             'creator': creator.username,
             'id': plan.id,
             'title': title,
+            'type': plan_type,
             'description': description,
             'state': '执行中',
             'files': [{'file_id': file_id, 'file_name': file.name, 'file_url': file_path} for (file_id, file, file_path)

+ 23 - 0
apps/plan/views/planview.py

@@ -145,3 +145,26 @@ class PlanEdit(APIView):
         executor, action, method = get_log(request)
         gen_log(action, "测试计划", plan.title, method, executor)
         return HttpResponse("编辑已保存")
+
+
+class PlanEditType(APIView):
+    # 登录权限验证
+    authentication_classes = []
+
+    @staticmethod
+    def post(request, plan_id, *args, **kwargs):
+        plan_type = request.POST.get('type')
+
+        plan = TestPlan.objects.filter(id=plan_id, delete=False)
+        if not plan:
+            logger.error("测试计划已删除或不存在")
+            return HttpResponse(status=404, content='测试计划已删除或不存在')
+        plan = plan[0]
+
+        plan.type = plan_type
+        plan.save()
+
+        executor, action, method = get_log(request)
+        gen_log(action, "测试计划类型", plan.title, method, executor)
+
+        return HttpResponse("编辑已保存")

+ 4 - 1
apps/software/urls.py

@@ -1,5 +1,6 @@
 from django.urls import path
 from .views.softwarelistview import SoftwareListView
+from .views.softwareplanview import SoftwarePlanView, SoftwareVersionPlanView
 from .views.softwareview import SoftwareView, SoftwareEdit
 from .views.report import Report
 from .views.versionlistview import VersionListView
@@ -12,5 +13,7 @@ urlpatterns = [
     path('<str:software_id>/edit', SoftwareEdit.as_view()),
     path('<str:software_id>/versions', VersionView.as_view()),
     path('<str:software_id>/versions/edit', VersionEdit.as_view()),
-    path('<str:software_id>/report', Report.as_view())
+    path('<str:software_id>/report', Report.as_view()),
+    path('<str:software_id>/plans', SoftwarePlanView.as_view()),
+    path('<str:software_id>/versions/plan', SoftwareVersionPlanView.as_view())
 ]

+ 106 - 0
apps/software/views/softwareplanview.py

@@ -0,0 +1,106 @@
+import datetime
+import json
+import logging
+
+from django.http import HttpResponse
+from rest_framework.response import Response
+from rest_framework.views import APIView
+
+from apps.log.models import get_log, gen_log
+from apps.plan.models import TestPlan
+from apps.software.models import Software
+from apps.task.models import TestTask
+from apps.user.middleware.rolecontrol import RoleControl
+from django.forms.models import model_to_dict
+
+from apps.user.models import User
+from utils.util_add_id import get_id
+
+logger = logging.getLogger('django')
+
+
+class SoftwarePlanView(APIView):
+    authentication_classes = []
+
+    # generate report
+    @staticmethod
+    @RoleControl
+    def get(request, software_id, *args, **kwargs):
+        software = Software.objects.filter(id=software_id, delete=False)
+        if not software:
+            logger.error("软件已删除或不存在")
+            return HttpResponse(status=404, content='软件已删除或不存在')
+
+        plan_all = TestPlan.objects.order_by('-create_time')
+        plan_all = plan_all.filter(software__id__contains=software_id)
+
+        info = []
+        plan_all = plan_all.filter(delete=False)
+        for plan in plan_all.all():
+            info.append({
+                'software_id': plan.software.id,
+                'software_name': plan.software.name,
+                'version': plan.version,
+                'creator_id': plan.creator.id,
+                'creator': plan.creator.username,
+                'id': plan.id,
+                'type': plan.type,
+                'title': plan.title,
+                'description': plan.description,
+                'state': plan.state,
+                'create_time': plan.create_time,
+                'update_time': plan.update_time,
+            })
+        return Response(info)
+
+
+class SoftwareVersionPlanView(APIView):
+    authentication_classes = []
+
+    # generate report
+    @staticmethod
+    @RoleControl
+    def post(request, software_id, *args, **kwargs):
+        params = json.loads(request.body)
+
+        version_number = params['version_number']
+        plan_ids = params['plan_ids']
+
+        software = Software.objects.filter(id=software_id, delete=False)
+        if not software:
+            logger.error("软件已删除或不存在")
+            return HttpResponse(status=404, content='软件已删除或不存在')
+        software = software[0]
+
+        plan_all = TestPlan.objects.order_by('-create_time').filter(delete=False)
+        plan_all = plan_all.filter(id__in=plan_ids)
+
+        for plan in plan_all:
+            create_time = update_time = datetime.datetime.now()
+            plan_info = model_to_dict(plan)
+
+            plan_info['id'] = get_id(TestPlan, "TestLaboratory_V1_Plan_1")
+            plan_info['version'] = version_number
+            plan_info['state'] = 0
+            plan_info['create_time'] = create_time
+            plan_info['update_time'] = update_time
+            plan_info['software'] = software
+            plan_info['creator'] = plan.creator
+
+            new_plan = TestPlan.objects.create(**plan_info)
+
+            tasks = plan.testtask_set.filter(delete=False)
+            if tasks:
+                for task in tasks:
+
+                    task_info = model_to_dict(task)
+                    task_info['id'] = get_id(TestTask, "TestLaboratory_V1_Task_1")
+                    task_info['state'] = 0
+                    task_info['create_time'] = create_time
+                    task_info['update_time'] = update_time
+                    task_info['plan'] = new_plan
+                    task_info['executor'] = task.executor
+                    new_task = TestTask.objects.create(**task_info)
+        executor, action, method = get_log(request)
+        gen_log(action, "版本测试计划", plan.title, method, executor)
+        return HttpResponse("关联成功")

BIN
db/permission.xlsx


BIN
db/role_permissions.xlsx


+ 344 - 0
logs/all-2023-02-01.log

@@ -0,0 +1,344 @@
+[INFO] [2023-02-01 11:19:48,022] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 15:28:51,111] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/users/login HTTP/1.1" 200 292
+[INFO] [2023-02-01 15:37:54,149] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/test-plans/ HTTP/1.1" 200 281
+[INFO] [2023-02-01 15:38:27,032] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/test-plans/ HTTP/1.1" 200 281
+[INFO] [2023-02-01 15:39:10,488] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/plan/views/planlistview.py changed, reloading.
+[INFO] [2023-02-01 15:39:11,259] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 15:39:16,450] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/test-plans/ HTTP/1.1" 200 303
+[INFO] [2023-02-01 15:39:24,123] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/test-plans/ HTTP/1.1" 200 291
+[INFO] [2023-02-01 16:36:42,326] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/plan/views/planview.py changed, reloading.
+[INFO] [2023-02-01 16:36:43,016] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 16:50:42,111] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/urls.py changed, reloading.
+[INFO] [2023-02-01 16:50:42,559] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 16:57:34,062] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/urls.py changed, reloading.
+[INFO] [2023-02-01 16:57:34,475] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 16:59:27,926] [basehttp.py:161] [basehttp:log_message] - "GET /api/v1/software/TestLaboratory_V1_Software_1/plans HTTP/1.1" 200 1814
+[INFO] [2023-02-01 17:04:49,460] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 17:04:50,446] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 17:07:28,163] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/urls.py changed, reloading.
+[INFO] [2023-02-01 17:07:29,057] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 17:08:38,780] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 17:08:39,460] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 17:11:30,660] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 200 2
+[INFO] [2023-02-01 17:11:44,749] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 17:11:45,966] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 17:12:46,571] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 17:12:47,225] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 17:13:03,133] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 17:13:03,546] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 17:13:12,141] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 17:13:12,529] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[ERROR] [2023-02-01 17:13:16,765] [log.py:224] [log:log_response] - Internal Server Error: /api/v1/software/TestLaboratory_V1_Software_1/versions/plan
+Traceback (most recent call last):
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
+    response = get_response(request)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
+    response = wrapped_callback(request, *callback_args, **callback_kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "/Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/user/middleware/rolecontrol.py", line 48, in __call__
+    return self.func(request, *args, **kwargs)
+  File "/Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py", line 60, in post
+    body = json.loads(request.body)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/request.py", line 416, in __getattr__
+    return getattr(self._request, attr)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/http/request.py", line 328, in body
+    raise RawPostDataException("You cannot access body after reading from request's data stream")
+django.http.request.RawPostDataException: You cannot access body after reading from request's data stream
+[ERROR] [2023-02-01 17:13:16,769] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 500 109512
+[INFO] [2023-02-01 17:13:49,992] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 17:13:50,447] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[ERROR] [2023-02-01 17:13:54,224] [log.py:224] [log:log_response] - Internal Server Error: /api/v1/software/TestLaboratory_V1_Software_1/versions/plan
+Traceback (most recent call last):
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
+    response = get_response(request)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
+    response = wrapped_callback(request, *callback_args, **callback_kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "/Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/user/middleware/rolecontrol.py", line 48, in __call__
+    return self.func(request, *args, **kwargs)
+  File "/Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py", line 60, in post
+    body = request.body
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/request.py", line 416, in __getattr__
+    return getattr(self._request, attr)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/http/request.py", line 328, in body
+    raise RawPostDataException("You cannot access body after reading from request's data stream")
+django.http.request.RawPostDataException: You cannot access body after reading from request's data stream
+[ERROR] [2023-02-01 17:13:54,226] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 500 109629
+[INFO] [2023-02-01 17:14:32,316] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 17:14:32,889] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[ERROR] [2023-02-01 17:14:36,429] [log.py:224] [log:log_response] - Internal Server Error: /api/v1/software/TestLaboratory_V1_Software_1/versions/plan
+Traceback (most recent call last):
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
+    response = get_response(request)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
+    response = wrapped_callback(request, *callback_args, **callback_kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "/Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/user/middleware/rolecontrol.py", line 48, in __call__
+    return self.func(request, *args, **kwargs)
+  File "/Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py", line 60, in post
+    body = request.body
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/request.py", line 416, in __getattr__
+    return getattr(self._request, attr)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/http/request.py", line 328, in body
+    raise RawPostDataException("You cannot access body after reading from request's data stream")
+django.http.request.RawPostDataException: You cannot access body after reading from request's data stream
+[ERROR] [2023-02-01 17:14:36,432] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 500 109617
+[INFO] [2023-02-01 17:15:24,962] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 17:15:26,048] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 17:15:34,817] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 200 2
+[INFO] [2023-02-01 17:21:00,359] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 17:21:00,998] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[ERROR] [2023-02-01 17:21:04,220] [log.py:224] [log:log_response] - Internal Server Error: /api/v1/software/TestLaboratory_V1_Software_1/versions/plan
+Traceback (most recent call last):
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
+    response = get_response(request)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
+    response = wrapped_callback(request, *callback_args, **callback_kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "/Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/user/middleware/rolecontrol.py", line 48, in __call__
+    return self.func(request, *args, **kwargs)
+  File "/Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py", line 60, in post
+    plan_id = params['plan_id']
+KeyError: 'plan_id'
+[ERROR] [2023-02-01 17:21:04,221] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 500 101237
+[INFO] [2023-02-01 17:21:16,053] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 17:21:16,541] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 17:21:18,932] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 200 2
+[INFO] [2023-02-01 17:21:34,487] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 17:21:34,873] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 17:21:37,111] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 200 2
+[INFO] [2023-02-01 17:24:58,603] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 17:24:59,045] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 17:27:05,993] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 17:27:06,518] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 17:27:08,709] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 200 2
+[INFO] [2023-02-01 17:27:19,778] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 17:27:20,232] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 17:27:22,129] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 200 2
+[INFO] [2023-02-01 17:27:56,736] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 17:27:57,141] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 17:27:59,343] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 200 2
+[INFO] [2023-02-01 17:28:05,847] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 17:28:06,174] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 17:28:08,229] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 200 2
+[INFO] [2023-02-01 20:17:57,503] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 20:17:58,214] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 20:18:26,578] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/test-tasks/beidou HTTP/1.1" 200 511
+[INFO] [2023-02-01 20:18:38,234] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/test-tasks/beidou HTTP/1.1" 200 512
+[INFO] [2023-02-01 20:18:43,441] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 200 2
+[INFO] [2023-02-01 20:19:44,757] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 20:19:45,310] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 20:21:00,622] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 20:21:01,217] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 20:21:05,944] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 200 2
+[INFO] [2023-02-01 20:23:13,540] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 20:23:14,161] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 20:30:29,393] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 20:30:30,048] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 20:32:49,591] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 20:32:50,312] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 20:34:39,704] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 20:34:40,175] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 20:34:47,791] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 200 2
+[INFO] [2023-02-01 20:35:12,840] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 20:35:13,284] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 20:35:17,131] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 200 2
+[INFO] [2023-02-01 20:37:15,871] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 20:37:16,704] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 20:38:51,260] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 20:38:52,039] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 20:40:03,825] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 20:40:04,668] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 20:41:06,817] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 20:41:07,703] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[ERROR] [2023-02-01 20:41:11,705] [log.py:224] [log:log_response] - Internal Server Error: /api/v1/software/TestLaboratory_V1_Software_1/versions/plan
+Traceback (most recent call last):
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
+    response = get_response(request)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
+    response = wrapped_callback(request, *callback_args, **callback_kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "/Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/user/middleware/rolecontrol.py", line 48, in __call__
+    return self.func(request, *args, **kwargs)
+  File "/Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py", line 80, in post
+    new_plan = TestPlan.objects.create(**plan_info)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method
+    return getattr(self.get_queryset(), name)(*args, **kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/db/models/query.py", line 451, in create
+    obj = self.model(**kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/db/models/base.py", line 485, in __init__
+    _setattr(self, field.name, rel_obj)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/db/models/fields/related_descriptors.py", line 215, in __set__
+    raise ValueError(
+ValueError: Cannot assign "'TestLaboratory_V1_Software_1'": "TestPlan.software" must be a "Software" instance.
+[ERROR] [2023-02-01 20:41:11,712] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 500 124261
+[INFO] [2023-02-01 20:43:59,490] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 20:43:59,869] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[ERROR] [2023-02-01 20:44:37,058] [log.py:224] [log:log_response] - Internal Server Error: /api/v1/software/TestLaboratory_V1_Software_1/versions/plan
+Traceback (most recent call last):
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
+    response = get_response(request)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
+    response = wrapped_callback(request, *callback_args, **callback_kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "/Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/user/middleware/rolecontrol.py", line 48, in __call__
+    return self.func(request, *args, **kwargs)
+  File "/Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py", line 86, in post
+    new_plan = TestPlan.objects.create(**plan_info)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method
+    return getattr(self.get_queryset(), name)(*args, **kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/db/models/query.py", line 451, in create
+    obj = self.model(**kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/db/models/base.py", line 485, in __init__
+    _setattr(self, field.name, rel_obj)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/db/models/fields/related_descriptors.py", line 215, in __set__
+    raise ValueError(
+ValueError: Cannot assign "<QuerySet [<Software: beidou专用>]>": "TestPlan.software" must be a "Software" instance.
+[ERROR] [2023-02-01 20:44:37,061] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 500 124613
+[INFO] [2023-02-01 20:44:56,132] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 20:44:56,698] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[ERROR] [2023-02-01 20:44:58,591] [log.py:224] [log:log_response] - Internal Server Error: /api/v1/software/TestLaboratory_V1_Software_1/versions/plan
+Traceback (most recent call last):
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
+    response = get_response(request)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
+    response = wrapped_callback(request, *callback_args, **callback_kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "/Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/user/middleware/rolecontrol.py", line 48, in __call__
+    return self.func(request, *args, **kwargs)
+  File "/Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py", line 87, in post
+    new_plan = TestPlan.objects.create(**plan_info)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method
+    return getattr(self.get_queryset(), name)(*args, **kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/db/models/query.py", line 451, in create
+    obj = self.model(**kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/db/models/base.py", line 485, in __init__
+    _setattr(self, field.name, rel_obj)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/db/models/fields/related_descriptors.py", line 215, in __set__
+    raise ValueError(
+ValueError: Cannot assign "'TestLaboratory_V1_User_1'": "TestPlan.creator" must be a "User" instance.
+[ERROR] [2023-02-01 20:44:58,602] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 500 124300
+[INFO] [2023-02-01 20:46:31,838] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 20:46:32,569] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[ERROR] [2023-02-01 20:46:33,867] [log.py:224] [log:log_response] - Internal Server Error: /api/v1/software/TestLaboratory_V1_Software_1/versions/plan
+Traceback (most recent call last):
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
+    response = get_response(request)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
+    response = wrapped_callback(request, *callback_args, **callback_kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
+    return view_func(*args, **kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
+    return self.dispatch(request, *args, **kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
+    response = self.handle_exception(exc)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception
+    self.raise_uncaught_exception(exc)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
+    raise exc
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
+    response = handler(request, *args, **kwargs)
+  File "/Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/user/middleware/rolecontrol.py", line 48, in __call__
+    return self.func(request, *args, **kwargs)
+  File "/Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py", line 101, in post
+    new_task = TestTask.objects.create(**task_info)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method
+    return getattr(self.get_queryset(), name)(*args, **kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/db/models/query.py", line 451, in create
+    obj = self.model(**kwargs)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/db/models/base.py", line 485, in __init__
+    _setattr(self, field.name, rel_obj)
+  File "/Users/liufan/program/software/python/miniforge3/lib/python3.9/site-packages/django/db/models/fields/related_descriptors.py", line 215, in __set__
+    raise ValueError(
+ValueError: Cannot assign "'TestLaboratory_V1_User_3'": "TestTask.executor" must be a "User" instance.
+[ERROR] [2023-02-01 20:46:33,875] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 500 126007
+[INFO] [2023-02-01 20:46:52,130] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 20:46:52,593] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 20:46:53,889] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 200 2
+[INFO] [2023-02-01 20:47:52,115] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 20:47:52,593] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 20:48:10,846] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 20:48:11,313] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 20:49:46,756] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 20:49:47,173] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 20:52:17,887] [autoreload.py:251] [autoreload:trigger_reload] - /Users/liufan/program/PYTHON/TestLaboratoryGit/TestLaboratory/apps/software/views/softwareplanview.py changed, reloading.
+[INFO] [2023-02-01 20:52:18,663] [autoreload.py:637] [autoreload:run_with_reloader] - Watching for file changes with StatReloader
+[INFO] [2023-02-01 20:52:22,982] [basehttp.py:161] [basehttp:log_message] - "POST /api/v1/software/TestLaboratory_V1_Software_1/versions/plan HTTP/1.1" 200 12
+[INFO] [2023-02-01 20:53:02,220] [basehttp.py:161] [basehttp:log_message] - "GET /api/v1/software/TestLaboratory_V1_Software_1/plans HTTP/1.1" 200 3660

+ 0 - 0
apps/software/tests/softwaretest.py → logs/error-2023-02-01.log


+ 0 - 0
apps/software/tests/__init__.py → logs/info-2023-02-01.log


+ 10 - 0
mysql-init/TestLaboratory.sql

@@ -547,6 +547,9 @@ INSERT INTO `permission` VALUES ('TestLaboratory_V1_Permission_41', '编辑北
 INSERT INTO `permission` VALUES ('TestLaboratory_V1_Permission_42', '删除北斗任务', '/api/v1/test-tasks/beidou/edit', 'DELETE', '2022-10-06 09:01:59.000000', '2022-10-06 09:02:03.000000', 0);
 INSERT INTO `permission` VALUES ('TestLaboratory_V1_Permission_43', '执行北斗任务', '/api/v1/test-tasks/beidou/.*/execute', 'POST', '2022-10-06 09:02:48.000000', '2022-10-06 09:02:53.000000', 0);
 INSERT INTO `permission` VALUES ('TestLaboratory_V1_Permission_44', '查看北斗任务执行结果', '/api/v1/test-tasks/beidou/.*', 'GET', '2022-10-06 09:03:27.000000', '2022-10-06 09:03:30.000000', 0);
+INSERT INTO `permission` VALUES ('TestLaboratory_V1_Permission_45', '编辑计划类型', '/api/v1/test-plans/.*/edit-type', 'POST', '2022-10-06 09:03:28.000000', '2022-10-06 09:03:31.000000', 0);
+INSERT INTO `permission` VALUES ('TestLaboratory_V1_Permission_46', '获取计划列表', '/api/v1/software/.*/plans', 'GET', '2022-10-06 09:03:29.000000', '2022-10-06 09:03:32.000000', 0);
+INSERT INTO `permission` VALUES ('TestLaboratory_V1_Permission_47', '添加测试计划', '/api/v1/software/.*/versions/plan', 'POST', '2022-10-06 09:03:30.000000', '2022-10-06 09:03:33.000000', 0);
 INSERT INTO `permission` VALUES ('TestLaboratory_V1_Permission_5', '删除测试目标', '/api/v1/software/.*', 'DELETE', '2021-07-14 10:26:40.000000', '2021-07-14 10:26:42.000000', 0);
 INSERT INTO `permission` VALUES ('TestLaboratory_V1_Permission_6', '生成测试报告', '/api/v1/software/.*/report', 'GET', '2021-07-14 10:27:43.000000', '2021-07-14 10:27:46.000000', 0);
 INSERT INTO `permission` VALUES ('TestLaboratory_V1_Permission_7', '新建版本', '/api/v1/software/.*/versions', 'POST', '2021-07-14 10:29:22.000000', '2021-07-14 10:29:25.000000', 0);
@@ -570,6 +573,7 @@ CREATE TABLE `plan` (
   `delete` tinyint(1) NOT NULL,
   `creator_id` varchar(128) DEFAULT NULL,
   `software_id` varchar(128) NOT NULL,
+  `type` varchar(30) DEFAULT NULL,
   PRIMARY KEY (`id`),
   KEY `plan_creator_id_c94ecd21_fk` (`creator_id`),
   KEY `plan_software_id_4b28cc2e_fk` (`software_id`),
@@ -661,6 +665,9 @@ INSERT INTO `role_permissions` VALUES (96, 'TestLaboratory_V1_Role_1', 'TestLabo
 INSERT INTO `role_permissions` VALUES (98, 'TestLaboratory_V1_Role_1', 'TestLaboratory_V1_Permission_42');
 INSERT INTO `role_permissions` VALUES (100, 'TestLaboratory_V1_Role_1', 'TestLaboratory_V1_Permission_43');
 INSERT INTO `role_permissions` VALUES (103, 'TestLaboratory_V1_Role_1', 'TestLaboratory_V1_Permission_44');
+INSERT INTO `role_permissions` VALUES (106, 'TestLaboratory_V1_Role_1', 'TestLaboratory_V1_Permission_45');
+INSERT INTO `role_permissions` VALUES (108, 'TestLaboratory_V1_Role_1', 'TestLaboratory_V1_Permission_46');
+INSERT INTO `role_permissions` VALUES (110, 'TestLaboratory_V1_Role_1', 'TestLaboratory_V1_Permission_47');
 INSERT INTO `role_permissions` VALUES (5, 'TestLaboratory_V1_Role_1', 'TestLaboratory_V1_Permission_5');
 INSERT INTO `role_permissions` VALUES (6, 'TestLaboratory_V1_Role_1', 'TestLaboratory_V1_Permission_6');
 INSERT INTO `role_permissions` VALUES (7, 'TestLaboratory_V1_Role_1', 'TestLaboratory_V1_Permission_7');
@@ -704,6 +711,9 @@ INSERT INTO `role_permissions` VALUES (97, 'TestLaboratory_V1_Role_2', 'TestLabo
 INSERT INTO `role_permissions` VALUES (99, 'TestLaboratory_V1_Role_2', 'TestLaboratory_V1_Permission_42');
 INSERT INTO `role_permissions` VALUES (101, 'TestLaboratory_V1_Role_2', 'TestLaboratory_V1_Permission_43');
 INSERT INTO `role_permissions` VALUES (104, 'TestLaboratory_V1_Role_2', 'TestLaboratory_V1_Permission_44');
+INSERT INTO `role_permissions` VALUES (107, 'TestLaboratory_V1_Role_2', 'TestLaboratory_V1_Permission_45');
+INSERT INTO `role_permissions` VALUES (109, 'TestLaboratory_V1_Role_2', 'TestLaboratory_V1_Permission_46');
+INSERT INTO `role_permissions` VALUES (111, 'TestLaboratory_V1_Role_2', 'TestLaboratory_V1_Permission_47');
 INSERT INTO `role_permissions` VALUES (26, 'TestLaboratory_V1_Role_2', 'TestLaboratory_V1_Permission_5');
 INSERT INTO `role_permissions` VALUES (27, 'TestLaboratory_V1_Role_2', 'TestLaboratory_V1_Permission_6');
 INSERT INTO `role_permissions` VALUES (28, 'TestLaboratory_V1_Role_2', 'TestLaboratory_V1_Permission_7');