소스 검색

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

刘凡 2 년 전
부모
커밋
5559ff545f

+ 1 - 1
Dockerfile

@@ -1,4 +1,4 @@
-From python:3.9
+FROM python:3.9
 
 
 MAINTAINER Liufan<1649750212@qq.com>
 MAINTAINER Liufan<1649750212@qq.com>
 ENV PYTHONUNBUFFERED 1
 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
 from django.db import models
 
 
 # Create your models here.
 # Create your models here.
-from TestLaboratory.settings import PLAN_ROOT
-from apps.file.models import FileManager
 from apps.software.models import Software
 from apps.software.models import Software
 from apps.user.models import User
 from apps.user.models import User
-from utils.util_add_id import gen_next_id
 
 
 
 
 class TestPlan(models.Model):
 class TestPlan(models.Model):
     id = models.CharField(max_length=128, unique=True, primary_key=True, verbose_name='测试计划编号',
     id = models.CharField(max_length=128, unique=True, primary_key=True, verbose_name='测试计划编号',
                           default='TestLaboratory_V1_Plan_1')
                           default='TestLaboratory_V1_Plan_1')
     title = models.CharField(max_length=30, verbose_name='测试计划标题')
     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='测试软件')
     software = models.ForeignKey(Software, on_delete=models.CASCADE, verbose_name='测试软件')
     version = models.CharField(max_length=20, verbose_name='软件版本')
     version = models.CharField(max_length=20, verbose_name='软件版本')
     creator = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, 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 django.urls import path
 from .views.planlistview import PlanListView
 from .views.planlistview import PlanListView
-from .views.planview import PlanView, PlanEdit
+from .views.planview import PlanView, PlanEdit, PlanEditType
 
 
 urlpatterns = [
 urlpatterns = [
     path('', PlanListView.as_view()),
     path('', PlanListView.as_view()),
     path('<str:plan_id>', PlanView.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 datetime
-import json
+import logging
 import os
 import os
 
 
+from django.http import HttpResponse
 from rest_framework.response import Response
 from rest_framework.response import Response
 from rest_framework.views import APIView
 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.file.models import FileManager
 from apps.log.models import get_log, gen_log
 from apps.log.models import get_log, gen_log
 from apps.plan.models import TestPlan
 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.middleware.rolecontrol import RoleControl
 from apps.user.models import User
 from apps.user.models import User
 from utils.util_add_id import gen_next_id, get_id
 from utils.util_add_id import gen_next_id, get_id
-from TestLaboratory.settings import PLAN_ROOT
 
 
-import logging
 logger = logging.getLogger('django')
 logger = logging.getLogger('django')
 
 
 
 
@@ -30,6 +29,7 @@ class PlanListView(APIView):
         software_id = request.POST.get('software_id')
         software_id = request.POST.get('software_id')
         version_number = request.POST.get('version_number')
         version_number = request.POST.get('version_number')
         title = request.POST.get('title')
         title = request.POST.get('title')
+        plan_type = request.POST.get('type')
         description = request.POST.get('description')
         description = request.POST.get('description')
         files = request.FILES.getlist('files')
         files = request.FILES.getlist('files')
         creator_id = request.POST.get('creator')
         creator_id = request.POST.get('creator')
@@ -97,7 +97,7 @@ class PlanListView(APIView):
         fids = fids[:-2]
         fids = fids[:-2]
 
 
         try:
         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,
                                            creator=creator, software=software, version=software_version.number,
                                            statement_file=fids,
                                            statement_file=fids,
                                            create_time=create_time, update_time=update_time)
                                            create_time=create_time, update_time=update_time)
@@ -115,6 +115,7 @@ class PlanListView(APIView):
             'creator': creator.username,
             'creator': creator.username,
             'id': plan.id,
             'id': plan.id,
             'title': title,
             'title': title,
+            'type': plan_type,
             'description': description,
             'description': description,
             'state': '执行中',
             'state': '执行中',
             'files': [{'file_id': file_id, 'file_name': file.name, 'file_url': file_path} for (file_id, file, file_path)
             '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)
         executor, action, method = get_log(request)
         gen_log(action, "测试计划", plan.title, method, executor)
         gen_log(action, "测试计划", plan.title, method, executor)
         return HttpResponse("编辑已保存")
         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 django.urls import path
 from .views.softwarelistview import SoftwareListView
 from .views.softwarelistview import SoftwareListView
+from .views.softwareplanview import SoftwarePlanView, SoftwareVersionPlanView
 from .views.softwareview import SoftwareView, SoftwareEdit
 from .views.softwareview import SoftwareView, SoftwareEdit
 from .views.report import Report
 from .views.report import Report
 from .views.versionlistview import VersionListView
 from .views.versionlistview import VersionListView
@@ -12,5 +13,7 @@ urlpatterns = [
     path('<str:software_id>/edit', SoftwareEdit.as_view()),
     path('<str:software_id>/edit', SoftwareEdit.as_view()),
     path('<str:software_id>/versions', VersionView.as_view()),
     path('<str:software_id>/versions', VersionView.as_view()),
     path('<str:software_id>/versions/edit', VersionEdit.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_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_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_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_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_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);
 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,
   `delete` tinyint(1) NOT NULL,
   `creator_id` varchar(128) DEFAULT NULL,
   `creator_id` varchar(128) DEFAULT NULL,
   `software_id` varchar(128) NOT NULL,
   `software_id` varchar(128) NOT NULL,
+  `type` varchar(30) DEFAULT NULL,
   PRIMARY KEY (`id`),
   PRIMARY KEY (`id`),
   KEY `plan_creator_id_c94ecd21_fk` (`creator_id`),
   KEY `plan_creator_id_c94ecd21_fk` (`creator_id`),
   KEY `plan_software_id_4b28cc2e_fk` (`software_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 (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 (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 (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 (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 (6, 'TestLaboratory_V1_Role_1', 'TestLaboratory_V1_Permission_6');
 INSERT INTO `role_permissions` VALUES (7, 'TestLaboratory_V1_Role_1', 'TestLaboratory_V1_Permission_7');
 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 (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 (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 (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 (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 (27, 'TestLaboratory_V1_Role_2', 'TestLaboratory_V1_Permission_6');
 INSERT INTO `role_permissions` VALUES (28, 'TestLaboratory_V1_Role_2', 'TestLaboratory_V1_Permission_7');
 INSERT INTO `role_permissions` VALUES (28, 'TestLaboratory_V1_Role_2', 'TestLaboratory_V1_Permission_7');