Django接口自動化平臺實現(三)

3.2?后臺?admin 添加數據

1)注冊模型類到?admin:

?

 1 from django.contrib import admin2 from . import models3 4 5 class ProjectAdmin(admin.ModelAdmin):6     list_display = ("id", "name", "proj_owner", "test_owner", "dev_owner", "desc", "create_time", "update_time")7 8 admin.site.register(models.Project, ProjectAdmin)9 
10 
11 class ModuleAdmin(admin.ModelAdmin):
12     list_display = ("id", "name", "belong_project", "test_owner", "desc", "create_time", "update_time")
13 
14 admin.site.register(models.Module, ModuleAdmin)

?

2)登錄 admin 系統,添加模塊數據

訪問:http://127.0.0.1:8000/admin/,進入模塊信息表,添加數據。

?

?

?

3.3 定義路由?

新增應用 urls.py 的路由配置:

?

from django.urls import path
from . import viewsurlpatterns = [path('',views.index),path('login/', views.login),path('logout/', views.logout),path('project/', views.project, name="project"),path('module/', views.module, name="module"),
]

?

路由地址“module”對應的視圖函數,指向 views.py 中的 module 方法,下一步我們添加下該方法的處理。

3.4 定義視圖函數

?

 1 from django.shortcuts import render, redirect, HttpResponse2 from django.contrib import auth  # Django用戶認證(Auth)組件一般用在用戶的登錄注冊上,用于判斷當前的用戶是否合法3 from django.contrib.auth.decorators import login_required4 from django.core.paginator import Paginator, PageNotAnInteger, InvalidPage5 from .form import UserForm6 import traceback7 from .models import Project, Module8 9 
10 # 封裝分頁處理
11 def get_paginator(request, data):
12     paginator = Paginator(data, 10)  # 默認每頁展示10條數據
13     # 獲取 url 后面的 page 參數的值, 首頁不顯示 page 參數, 默認值是 1
14     page = request.GET.get('page')
15     try:
16         paginator_pages = paginator.page(page)
17     except PageNotAnInteger:
18         # 如果請求的頁數不是整數, 返回第一頁。
19         paginator_pages = paginator.page(1)
20     except InvalidPage:
21         # 如果請求的頁數不存在, 重定向頁面
22         return HttpResponse('找不到頁面的內容')
23     return paginator_pages
24 
25 
26 @login_required
27 def project(request):
28     print("request.user.is_authenticated: ", request.user.is_authenticated)
29     projects = Project.objects.filter().order_by('-id')
30     print("projects:", projects)
31     return render(request, 'project.html', {'projects': get_paginator(request, projects)})
32 
33 
34 @login_required
35 def module(request):
36     if request.method == "GET":  # 請求get時候,id倒序查詢所有的模塊數據
37         modules = Module.objects.filter().order_by('-id')
38         return render(request, 'module.html', {'modules': get_paginator(request, modules)})
39     else:  # 否則就是Post請求,會根據輸入內容,使用模糊的方式查找所有的項目
40         proj_name = request.POST['proj_name']
41         projects = Project.objects.filter(name__contains=proj_name.strip())
42         projs = [proj.id for proj in projects]
43         modules = Module.objects.filter(belong_project__in=projs)  # 把項目中所有的模塊都找出來
44         return render(request, 'module.html', {'modules': get_paginator(request, modules), 'proj_name': proj_name})
45 
46 
47 # 默認頁的視圖函數
48 @login_required
49 def index(request):
50     return render(request, 'index.html')
51 
52 
53 # 登錄頁的視圖函數
54 def login(request):
55     print("request.session.items(): {}".format(request.session.items()))  # 打印session信息
56     if request.session.get('is_login', None):
57         return redirect('/')
58     # 如果是表單提交行為,則進行登錄校驗
59     if request.method == "POST":
60         login_form = UserForm(request.POST)
61         message = "請檢查填寫的內容!"
62         if login_form.is_valid():
63             username = login_form.cleaned_data['username']
64             password = login_form.cleaned_data['password']
65             try:
66                 # 使用django提供的身份驗證功能
67                 user = auth.authenticate(username=username, password=password)  # 從auth_user表中匹配信息,匹配到則返回用戶對象
68                 if user is not None:
69                     print("用戶【%s】登錄成功" % username)
70                     auth.login(request, user)
71                     request.session['is_login'] = True
72                     # 登錄成功,跳轉主頁
73                     return redirect('/')
74                 else:
75                     message = "用戶名不存在或者密碼不正確!"
76             except:
77                 traceback.print_exc()
78                 message = "登錄程序出現異常"
79         # 用戶名或密碼為空,返回登錄頁和錯誤提示信息
80         else:
81             return render(request, 'login.html', locals())
82     # 不是表單提交,代表只是訪問登錄頁
83     else:
84         login_form = UserForm()
85         return render(request, 'login.html', locals())
86 
87 
88 # 注冊頁的視圖函數
89 def register(request):
90     return render(request, 'register.html')
91 
92 
93 # 登出的視圖函數:重定向至login視圖函數
94 @login_required
95 def logout(request):
96     auth.logout(request)
97     request.session.flush()
98     return redirect("/login/")

?

3.5 定義模板

1)新增 templates/module.html 模板

?

 1 {% extends 'base.html' %}2 {% load static %}3 {% block title %}模塊{% endblock %}4 5 {% block content %}6 <form action="{% url 'module'%}" method="POST">7     {% csrf_token %}8     <input style="margin-left: 5px;" type="text" name="proj_name" value="{{ proj_name }}" placeholder="輸入項目名稱搜索模塊">9     <input type="submit" value="搜索">
10 </form>
11 
12 <div class="table-responsive">
13 
14     <table class="table table-striped">
15         <thead>
16         <tr>
17             <th>id</th>
18             <th>模塊名稱</th>
19             <th>所屬項目</th>
20             <th>測試負責人</th>
21             <th>模塊描述</th>
22             <th>創建時間</th>
23             <th>更新時間</th>
24             <th>測試結果統計</th>
25         </tr>
26         </thead>
27         <tbody>
28 
29         {% for module in modules %}
30         <tr>
31             <td>{{ module.id }}</td>
32             <td><a href="">{{ module.name }}</a></td>
33             <td>{{ module.belong_project.name }}</td>
34             <td>{{ module.test_owner }}</td>
35             <td>{{ module.desc }}</td>
36             <td>{{ module.create_time|date:"Y-n-d H:i" }}</td>
37             <td>{{ module.update_time|date:"Y-n-d H:i" }}</td>
38             <td><a href="">查看</a></td>
39         </tr>
40         {% endfor %}
41         
42         </tbody>
43     </table>
44 </div>
45 
46 {# 實現分頁標簽的代碼 #}
47 {# 這里使用 bootstrap 渲染頁面 #}
48 <div id="pages" class="text-center">
49     <nav>
50         <ul class="pagination">
51             <li class="step-links">
52                 {% if modules.has_previous %}
53                 <a class='active' href="?page={{ modules.previous_page_number }}">上一頁</a>
54                 {% endif %}
55 
56                 <span class="current">
57                     第 {{ modules.number }} 頁 / 共 {{ modules.paginator.num_pages }} 頁</span>
58 
59                 {% if modules.has_next %}
60                 <a class='active' href="?page={{ modules.next_page_number }}">下一頁</a>
61                 {% endif %}
62             </li>
63         </ul>
64     </nav>
65 </div>
66 {% endblock %}

?

2)修改 base.html 模板,新增模塊菜單欄:

?

 1 <!DOCTYPE html>2 <html lang="zh-CN">3 {% load static %}4 <head>5     <meta charset="utf-8">6     <meta http-equiv="X-UA-Compatible" content="IE=edge">7     <meta name="viewport" content="width=device-width, initial-scale=1">8     <!-- 上述3個meta標簽*必須*放在最前面,任何其他內容都*必須*跟隨其后! -->9     <title>{% block title %}base{% endblock %}</title>
10 
11     <!-- Bootstrap -->
12     <link href="{% static 'bootstrap/css/bootstrap.min.css' %}" rel="stylesheet">
13 
14 
15     <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
16     <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
17     <!--[if lt IE 9]>
18     <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
19     <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
20     <![endif]-->
21     {% block css %}{% endblock %}
22 </head>
23 <body>
24 <nav class="navbar navbar-default">
25     <div class="container-fluid">
26         <!-- Brand and toggle get grouped for better mobile display -->
27         <div class="navbar-header">
28             <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#my-nav"
29                     aria-expanded="false">
30                 <span class="sr-only">切換導航條</span>
31                 <span class="icon-bar"></span>
32                 <span class="icon-bar"></span>
33                 <span class="icon-bar"></span>
34             </button>
35             <a class="navbar-brand" href="/">自動化測試平臺</a>
36         </div>
37 
38         <div class="collapse navbar-collapse" id="my-nav">
39             <ul class="nav navbar-nav">
40                 <li class="active"><a href="/project/">項目</a></li>
41                 <li class="active"><a href="/module/">模塊</a></li>
42             </ul>
43             <ul class="nav navbar-nav navbar-right">
44                 {% if request.user.is_authenticated %}
45                 <li><a href="#">當前在線:{{ request.user.username }}</a></li>
46                 <li><a href="/logout">登出</a></li>
47                 {% else %}
48                 <li><a href="/login">登錄</a></li>
49 
50                 {% endif %}
51             </ul>
52         </div><!-- /.navbar-collapse -->
53     </div><!-- /.container-fluid -->
54 </nav>
55 
56 {% block content %}{% endblock %}
57 
58 
59 <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
60 <script src="{% static 'js/jquery-3.4.1.js' %}"></script>
61 <!-- Include all compiled plugins (below), or include individual files as needed -->
62 <script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script>
63 </body>
64 </html>

?

?

4. 測試用例

?

4.1 定義模型類

1)在應用 models.py 中增加 TestCase 模型類:

?

 1 from django.db import models2 from smart_selects.db_fields import GroupedForeignKey  # 后臺級聯選擇3 from django.contrib.auth.models import User4 5 6 class Project(models.Model):7     id = models.AutoField(primary_key=True)8     name = models.CharField('項目名稱', max_length=50, unique=True, null=False)9     proj_owner = models.CharField('項目負責人', max_length=20, null=False)
10     test_owner = models.CharField('測試負責人', max_length=20, null=False)
11     dev_owner = models.CharField('開發負責人', max_length=20, null=False)
12     desc = models.CharField('項目描述', max_length=100, null=True)
13     create_time = models.DateTimeField('項目創建時間', auto_now_add=True)
14     update_time = models.DateTimeField('項目更新時間', auto_now=True, null=True)
15 
16     def __str__(self):
17         return self.name
18 
19     class Meta:
20         verbose_name = '項目信息表'
21         verbose_name_plural = '項目信息表'
22 
23 
24 class Module(models.Model):
25     id = models.AutoField(primary_key=True)
26     name = models.CharField('模塊名稱', max_length=50, null=False)
27     belong_project = models.ForeignKey(Project, on_delete=models.CASCADE)
28     test_owner = models.CharField('測試負責人', max_length=50, null=False)
29     desc = models.CharField('簡要描述', max_length=100, null=True)
30     create_time = models.DateTimeField('創建時間', auto_now_add=True)
31     update_time = models.DateTimeField('更新時間', auto_now=True, null=True)
32 
33     def __str__(self):
34         return self.name
35 
36     class Meta:
37         verbose_name = '模塊信息表'
38         verbose_name_plural = '模塊信息表'
39 
40 
41 class TestCase(models.Model):
42     id = models.AutoField(primary_key=True)
43     case_name = models.CharField('用例名稱', max_length=50, null=False)  # 如 register
44     belong_project = models.ForeignKey(Project, on_delete=models.CASCADE, verbose_name='所屬項目')
45     belong_module = GroupedForeignKey(Module, "belong_project", on_delete=models.CASCADE, verbose_name='所屬模塊')
46     request_data = models.CharField('請求數據', max_length=1024, null=False, default='')
47     uri = models.CharField('接口地址', max_length=1024, null=False, default='')
48     assert_key = models.CharField('斷言內容', max_length=1024, null=True)
49     maintainer = models.CharField('編寫人員', max_length=1024, null=False, default='')
50     extract_var = models.CharField('提取變量表達式', max_length=1024, null=True)  # 示例:userid||userid": (\d+)
51     request_method = models.CharField('請求方式', max_length=1024, null=True)
52     status = models.IntegerField(null=True, help_text="0:表示有效,1:表示無效,用于軟刪除")
53     created_time = models.DateTimeField('創建時間', auto_now_add=True)
54     updated_time = models.DateTimeField('更新時間', auto_now=True, null=True)
55     user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='責任人', null=True)
56 
57     def __str__(self):
58         return self.case_name
59 
60     class Meta:
61         verbose_name = '測試用例表'
62         verbose_name_plural = '測試用例表'

?

GroupedForeignKey 可以支持在 admin 新增數據時,展示該模型類的關聯表數據。(需提前安裝:pip install django-smart-selects)

2)數據遷移

在項目目錄下,執行以下兩個命令進行數據遷移(將模型類轉換成數據庫表):

python manage.py makemigrations  # 生成遷移文件(模型類的信息)
python manage.py migrate  # 執行開始遷移(將模型類信息轉換成數據庫表)

?

4.2 后臺 admin 添加數據

1)注冊模型類到 admin

應用 admin.py 文件中增加如下代碼:注冊 TestCase 模型類到 admin 后臺系統。

?

 1 from django.contrib import admin2 from . import models3 4 5 class ProjectAdmin(admin.ModelAdmin):6     list_display = ("id", "name", "proj_owner", "test_owner", "dev_owner", "desc", "create_time", "update_time")7 8 admin.site.register(models.Project, ProjectAdmin)9 
10 
11 class ModuleAdmin(admin.ModelAdmin):
12     list_display = ("id", "name", "belong_project", "test_owner", "desc", "create_time", "update_time")
13 
14 admin.site.register(models.Module, ModuleAdmin)
15 
16 
17 class TestCaseAdmin(admin.ModelAdmin):
18     list_display = (
19         "id", "case_name", "belong_project", "belong_module", "request_data", "uri", "assert_key", "maintainer",
20         "extract_var", "request_method", "status", "created_time", "updated_time", "user")
21 
22 admin.site.register(models.TestCase, TestCaseAdmin)

?

2)登錄 admin 系統,添加用例數據

訪問?http://127.0.0.1:8000/admin/,進入測試用例表,添加數據:

?

添加用例數據時,頁面如下:

  • 所屬項目和所屬模塊下拉選項是根據模型類中的 GroupedForeignKey 屬性生成的,方便我們正確的關聯數據。?
  • 請求數據、斷言內容、提取變量表達式等字段的定義,需要根據接口業務邏輯,以及后續運行邏輯的設計來輸入。?

?

?

添加數據后如下所示:?

?

4.3 定義路由?

應用 urls.py:

?

from django.urls import path
from . import viewsurlpatterns = [path('', views.index),path('login/', views.login),path('logout/', views.logout),path('project/', views.project, name='project'),path('module/', views.module, name='module'),path('test_case/', views.test_case, name="test_case"),
]

?

4.4 定義視圖函數

?

  1 from django.shortcuts import render, redirect, HttpResponse2 from django.contrib import auth  # Django用戶認證(Auth)組件一般用在用戶的登錄注冊上,用于判斷當前的用戶是否合法3 from django.contrib.auth.decorators import login_required4 from django.core.paginator import Paginator, PageNotAnInteger, InvalidPage5 from .form import UserForm6 import traceback7 from .models import Project, Module, TestCase8 9 10 # 封裝分頁處理11 def get_paginator(request, data):12     paginator = Paginator(data, 10)  # 默認每頁展示10條數據13     # 獲取 url 后面的 page 參數的值, 首頁不顯示 page 參數, 默認值是 114     page = request.GET.get('page')15     try:16         paginator_pages = paginator.page(page)17     except PageNotAnInteger:18         # 如果請求的頁數不是整數, 返回第一頁。19         paginator_pages = paginator.page(1)20     except InvalidPage:21         # 如果請求的頁數不存在, 重定向頁面22         return HttpResponse('找不到頁面的內容')23     return paginator_pages24 25 26 # 項目菜單27 @login_required28 def project(request):29     print("request.user.is_authenticated: ", request.user.is_authenticated)30     projects = Project.objects.filter().order_by('-id')31     print("projects:", projects)32     return render(request, 'project.html', {'projects': get_paginator(request, projects)})33 34 35 # 模塊菜單36 @login_required37 def module(request):38     if request.method == "GET":  # 請求get時候,id倒序查詢所有的模塊數據39         modules = Module.objects.filter().order_by('-id')40         return render(request, 'module.html', {'modules': get_paginator(request, modules)})41     else:  # 否則就是Post請求,會根據輸入內容,使用模糊的方式查找所有的項目42         proj_name = request.POST['proj_name']43         projects = Project.objects.filter(name__contains=proj_name.strip())44         projs = [proj.id for proj in projects]45         modules = Module.objects.filter(belong_project__in=projs)  # 把項目中所有的模塊都找出來46         return render(request, 'module.html', {'modules': get_paginator(request, modules), 'proj_name': proj_name})47 48 49 # 測試用例菜單50 @login_required51 def test_case(request):52     print("request.session['is_login']: {}".format(request.session['is_login']))53     test_cases = ""54     if request.method == "GET":55         test_cases = TestCase.objects.filter().order_by('id')56         print("testcases in testcase: {}".format(test_cases))57     elif request.method == "POST":58         print("request.POST: {}".format(request.POST))59         test_case_id_list = request.POST.getlist('testcases_list')60         if test_case_id_list:61             test_case_id_list.sort()62             print("test_case_id_list: {}".format(test_case_id_list))63         test_cases = TestCase.objects.filter().order_by('id')64     return render(request, 'test_case.html', {'test_cases': get_paginator(request, test_cases)})65 66 67 # 默認頁的視圖函數68 @login_required69 def index(request):70     return render(request, 'index.html')71 72 73 # 登錄頁的視圖函數74 def login(request):75     print("request.session.items(): {}".format(request.session.items()))  # 打印session信息76     if request.session.get('is_login', None):77         return redirect('/')78     # 如果是表單提交行為,則進行登錄校驗79     if request.method == "POST":80         login_form = UserForm(request.POST)81         message = "請檢查填寫的內容!"82         if login_form.is_valid():83             username = login_form.cleaned_data['username']84             password = login_form.cleaned_data['password']85             try:86                 # 使用django提供的身份驗證功能87                 user = auth.authenticate(username=username, password=password)  # 從auth_user表中匹配信息,匹配到則返回用戶對象88                 if user is not None:89                     print("用戶【%s】登錄成功" % username)90                     auth.login(request, user)91                     request.session['is_login'] = True92                     # 登錄成功,跳轉主頁93                     return redirect('/')94                 else:95                     message = "用戶名不存在或者密碼不正確!"96             except:97                 traceback.print_exc()98                 message = "登錄程序出現異常"99         # 用戶名或密碼為空,返回登錄頁和錯誤提示信息
100         else:
101             return render(request, 'login.html', locals())
102     # 不是表單提交,代表只是訪問登錄頁
103     else:
104         login_form = UserForm()
105         return render(request, 'login.html', locals())
106 
107 
108 # 注冊頁的視圖函數
109 def register(request):
110     return render(request, 'register.html')
111 
112 
113 # 登出的視圖函數:重定向至login視圖函數
114 @login_required
115 def logout(request):
116     auth.logout(request)
117     request.session.flush()
118     return redirect("/login/")

?

4.5 定義模板文件

1)新增 templates/test_case.html?模板:

?

 1 {% extends 'base.html' %}2 {% load static %}3 {% block title %}測試用例{% endblock %}4 5 {% block content %}6 <form action="" method="POST">7     {% csrf_token %}8     <div class="table-responsive">9         <table class="table table-striped">
10             <thead>
11             <tr>
12                 <th>用例名稱</th>
13                 <th>所屬項目</th>
14                 <th>所屬模塊</th>
15                 <th>接口地址</th>
16                 <th>請求方式</th>
17                 <th>請求數據</th>
18                 <th>斷言key</th>
19                 <th>提取變量表達式</th>
20             </tr>
21             </thead>
22             <tbody>
23 
24             {% for test_case in test_cases %}
25             <tr>
26                 <td><a href="{% url 'test_case_detail' test_case.id%}">{{ test_case.case_name }}</a></td>
27                 <td>{{ test_case.belong_project.name }}</td>
28                 <td>{{ test_case.belong_module.name }}</td>
29                 <td>{{ test_case.uri }}</td>
30                 <td>{{ test_case.request_method }}</td>
31                 <td>{{ test_case.request_data }}</td>
32                 <td>{{ test_case.assert_key }}</td>
33                 <td>{{ test_case.extract_var }}</td>
34             </tr>
35             {% endfor %}
36             </tbody>
37         </table>
38 
39     </div>
40 </form>
41 {# 實現分頁標簽的代碼 #}
42 {# 這里使用 bootstrap 渲染頁面 #}
43 <div id="pages" class="text-center">
44     <nav>
45         <ul class="pagination">
46             <li class="step-links">
47                 {% if test_cases.has_previous %}
48                 <a class='active' href="?page={{ test_cases.previous_page_number }}">上一頁</a>
49                 {% endif %}
50 
51                 <span class="current">
52                     第 {{ test_cases.number }} 頁 / 共 {{ test_cases.paginator.num_pages }} 頁</span>
53 
54                 {% if test_cases.has_next %}
55                 <a class='active' href="?page={{ test_cases.next_page_number }}">下一頁</a>
56                 {% endif %}
57             </li>
58         </ul>
59     </nav>
60 </div>
61 {% endblock %}

?

2)修改?base.html?模板:增加測試用例菜單。

?

 1 <!DOCTYPE html>2 <html lang="zh-CN">3 {% load static %}4 <head>5     <meta charset="utf-8">6     <meta http-equiv="X-UA-Compatible" content="IE=edge">7     <meta name="viewport" content="width=device-width, initial-scale=1">8     <!-- 上述3個meta標簽*必須*放在最前面,任何其他內容都*必須*跟隨其后! -->9     <title>{% block title %}base{% endblock %}</title>
10 
11     <!-- Bootstrap -->
12     <link href="{% static 'bootstrap/css/bootstrap.min.css' %}" rel="stylesheet">
13 
14 
15     <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
16     <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
17     <!--[if lt IE 9]>
18     <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
19     <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
20     <![endif]-->
21     {% block css %}{% endblock %}
22 </head>
23 <body>
24 <nav class="navbar navbar-default">
25     <div class="container-fluid">
26         <!-- Brand and toggle get grouped for better mobile display -->
27         <div class="navbar-header">
28             <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#my-nav"
29                     aria-expanded="false">
30                 <span class="sr-only">切換導航條</span>
31                 <span class="icon-bar"></span>
32                 <span class="icon-bar"></span>
33                 <span class="icon-bar"></span>
34             </button>
35             <a class="navbar-brand" href="/">自動化測試平臺</a>
36         </div>
37 
38         <div class="collapse navbar-collapse" id="my-nav">
39             <ul class="nav navbar-nav">
40                 <li class="active"><a href="/project/">項目</a></li>
41                 <li class="active"><a href="/module/">模塊</a></li>
42                 <li class="active"><a href="/test_case/">測試用例</a></li>
43             </ul>
44             <ul class="nav navbar-nav navbar-right">
45                 {% if request.user.is_authenticated %}
46                 <li><a href="#">當前在線:{{ request.user.username }}</a></li>
47                 <li><a href="/logout">登出</a></li>
48                 {% else %}
49                 <li><a href="/login">登錄</a></li>
50 
51                 {% endif %}
52             </ul>
53         </div><!-- /.navbar-collapse -->
54     </div><!-- /.container-fluid -->
55 </nav>
56 
57 {% block content %}{% endblock %}
58 
59 
60 <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
61 <script src="{% static 'js/jquery-3.4.1.js' %}"></script>
62 <!-- Include all compiled plugins (below), or include individual files as needed -->
63 <script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script>
64 </body>
65 </html>

?

4.6 用例詳情

目前用例列表中的字段僅包含用例的基本信息,下面繼續加一下(點擊用例名稱跳轉)用例詳情頁面,用于展示用例的全部字段信息,如創建時間、更新時間、維護人、創建人。

?

1)新增用例詳情的路由配置

?

from django.urls import path, re_path
from . import viewsurlpatterns = [path('', views.index),path('login/', views.login),path('logout/', views.logout),path('project/', views.project, name='project'),path('module/', views.module, name='module'),path('test_case/', views.test_case, name="test_case"),re_path('test_case_detail/(?P<test_case_id>[0-9]+)', views.test_case_detail, name="test_case_detail"),
]

?

由于用例詳情路由地址需要傳路由變量“test_case_id”,該變量需要通過正則表達式進行匹配,在 Django2.0 后,路由地址用到正則時需要用到 re_path 來解析,便于 Django 正確的匹配視圖函數,以及在瀏覽器地址欄正確的展示 url 地址。

2)增加視圖函數

?

  1 from django.shortcuts import render, redirect, HttpResponse2 from django.contrib import auth  # Django用戶認證(Auth)組件一般用在用戶的登錄注冊上,用于判斷當前的用戶是否合法3 from django.contrib.auth.decorators import login_required4 from django.core.paginator import Paginator, PageNotAnInteger, InvalidPage5 from .form import UserForm6 import traceback7 from .models import Project, Module, TestCase8 9 10 # 封裝分頁處理11 def get_paginator(request, data):12     paginator = Paginator(data, 10)  # 默認每頁展示10條數據13     # 獲取 url 后面的 page 參數的值, 首頁不顯示 page 參數, 默認值是 114     page = request.GET.get('page')15     try:16         paginator_pages = paginator.page(page)17     except PageNotAnInteger:18         # 如果請求的頁數不是整數, 返回第一頁。19         paginator_pages = paginator.page(1)20     except InvalidPage:21         # 如果請求的頁數不存在, 重定向頁面22         return HttpResponse('找不到頁面的內容')23     return paginator_pages24 25 26 # 項目菜單27 @login_required28 def project(request):29     print("request.user.is_authenticated: ", request.user.is_authenticated)30     projects = Project.objects.filter().order_by('-id')31     print("projects:", projects)32     return render(request, 'project.html', {'projects': get_paginator(request, projects)})33 34 35 # 模塊菜單36 @login_required37 def module(request):38     if request.method == "GET":  # 請求get時候,id倒序查詢所有的模塊數據39         modules = Module.objects.filter().order_by('-id')40         return render(request, 'module.html', {'modules': get_paginator(request, modules)})41     else:  # 否則就是Post請求,會根據輸入內容,使用模糊的方式查找所有的項目42         proj_name = request.POST['proj_name']43         projects = Project.objects.filter(name__contains=proj_name.strip())44         projs = [proj.id for proj in projects]45         modules = Module.objects.filter(belong_project__in=projs)  # 把項目中所有的模塊都找出來46         return render(request, 'module.html', {'modules': get_paginator(request, modules), 'proj_name': proj_name})47 48 49 # 測試用例菜單50 @login_required51 def test_case(request):52     print("request.session['is_login']: {}".format(request.session['is_login']))53     test_cases = ""54     if request.method == "GET":55         test_cases = TestCase.objects.filter().order_by('id')56         print("testcases in testcase: {}".format(test_cases))57     elif request.method == "POST":58         print("request.POST: {}".format(request.POST))59         test_case_id_list = request.POST.getlist('testcases_list')60         if test_case_id_list:61             test_case_id_list.sort()62             print("test_case_id_list: {}".format(test_case_id_list))63         test_cases = TestCase.objects.filter().order_by('id')64     return render(request, 'test_case.html', {'test_cases': get_paginator(request, test_cases)})65 66 67 # 用例詳情68 @login_required69 def test_case_detail(request, test_case_id):70     test_case_id = int(test_case_id)71     test_case = TestCase.objects.get(id=test_case_id)72     print("test_case: {}".format(test_case))73     print("test_case.id: {}".format(test_case.id))74     print("test_case.belong_project: {}".format(test_case.belong_project))75 76     return render(request, 'test_case_detail.html', {'test_case': test_case})77 78 79 # 默認頁的視圖函數80 @login_required81 def index(request):82     return render(request, 'index.html')83 84 85 # 登錄頁的視圖函數86 def login(request):87     print("request.session.items(): {}".format(request.session.items()))  # 打印session信息88     if request.session.get('is_login', None):89         return redirect('/')90     # 如果是表單提交行為,則進行登錄校驗91     if request.method == "POST":92         login_form = UserForm(request.POST)93         message = "請檢查填寫的內容!"94         if login_form.is_valid():95             username = login_form.cleaned_data['username']96             password = login_form.cleaned_data['password']97             try:98                 # 使用django提供的身份驗證功能99                 user = auth.authenticate(username=username, password=password)  # 從auth_user表中匹配信息,匹配到則返回用戶對象
100                 if user is not None:
101                     print("用戶【%s】登錄成功" % username)
102                     auth.login(request, user)
103                     request.session['is_login'] = True
104                     # 登錄成功,跳轉主頁
105                     return redirect('/')
106                 else:
107                     message = "用戶名不存在或者密碼不正確!"
108             except:
109                 traceback.print_exc()
110                 message = "登錄程序出現異常"
111         # 用戶名或密碼為空,返回登錄頁和錯誤提示信息
112         else:
113             return render(request, 'login.html', locals())
114     # 不是表單提交,代表只是訪問登錄頁
115     else:
116         login_form = UserForm()
117         return render(request, 'login.html', locals())
118 
119 
120 # 注冊頁的視圖函數
121 def register(request):
122     return render(request, 'register.html')
123 
124 
125 # 登出的視圖函數:重定向至login視圖函數
126 @login_required
127 def logout(request):
128     auth.logout(request)
129     request.session.flush()
130     return redirect("/login/")

?

3)新增 templates/test_case_detail.html 模板

?

 1 {% extends 'base.html' %}2 {% load static %}3 {% block title %}用例詳情{% endblock %}4 5 {% block content %}6 <div class="table-responsive">7     <table class="table table-striped">8         <thead>9         <tr>
10             <th width="3%">id</th>
11             <th width="4%">接口名稱</th>
12             <th width="6%">所屬項目</th>
13             <th width="6%">所屬模塊</th>
14             <th width="6%">接口地址</th>
15             <th width="10%">請求數據</th>
16             <th width="8%">斷言內容</th>
17             <th width="4%">編寫人員</th>
18             <th width="8%">提取變量表達式</th>
19             <th width="4%">維護人</th>
20             <th width="4%">創建人</th>
21             <th width="6%">創建時間</th>
22             <th width="6%">更新時間</th>
23         </tr>
24         </thead>
25         <tbody>
26         <tr>
27             <td>{{ test_case.id }}</td>
28             <td>{{ test_case.case_name }}</td>
29             <td>{{ test_case.belong_project }}</td>
30             <td>{{ test_case.belong_module }}</td>
31             <td>{{ test_case.uri }}</td>
32             <td>{{ test_case.request_data }}</td>
33             <td>{{ test_case.assert_key }}</td>
34             <td>{{ test_case.maintainer }}</td>
35             <td>{{ test_case.extract_var }}</td>
36             <td>{{ test_case.maintainer }}</td>
37             <td>{{ test_case.user.username }}</td>
38             <td>{{ test_case.created_time|date:"Y-n-d H:i" }}</td>
39             <td>{{ test_case.updated_time|date:"Y-n-d H:i" }}</td>
40         </tr>
41         </tbody>
42     </table>
43 </div>
44 {% endblock %}

?

4)修改 test_case.html 模板

添加用例名稱的鏈接為用例詳情路由地址:

?

 1 {% extends 'base.html' %}2 {% load static %}3 {% block title %}測試用例{% endblock %}4 5 {% block content %}6 <form action="" method="POST">7     {% csrf_token %}8     <div class="table-responsive">9         <table class="table table-striped">
10             <thead>
11             <tr>
12                 <th>用例名稱</th>
13                 <th>所屬項目</th>
14                 <th>所屬模塊</th>
15                 <th>接口地址</th>
16                 <th>請求方式</th>
17                 <th>請求數據</th>
18                 <th>斷言key</th>
19                 <th>提取變量表達式</th>
20             </tr>
21             </thead>
22             <tbody>
23 
24             {% for test_case in test_cases %}
25             <tr>
26                 <td><a href="{% url 'test_case_detail' test_case.id%}">{{ test_case.case_name }}</a></td>
27                 <td>{{ test_case.belong_project.name }}</td>
28                 <td>{{ test_case.belong_module.name }}</td>
29                 <td>{{ test_case.uri }}</td>
30                 <td>{{ test_case.request_method }}</td>
31                 <td>{{ test_case.request_data }}</td>
32                 <td>{{ test_case.assert_key }}</td>
33                 <td>{{ test_case.extract_var }}</td>
34             </tr>
35             {% endfor %}
36             </tbody>
37         </table>
38 
39     </div>
40 </form>
41 {# 實現分頁標簽的代碼 #}
42 {# 這里使用 bootstrap 渲染頁面 #}
43 <div id="pages" class="text-center">
44     <nav>
45         <ul class="pagination">
46             <li class="step-links">
47                 {% if test_cases.has_previous %}
48                 <a class='active' href="?page={{ test_cases.previous_page_number }}">上一頁</a>
49                 {% endif %}
50 
51                 <span class="current">
52                     第 {{ test_cases.number }} 頁 / 共 {{ test_cases.paginator.num_pages }} 頁</span>
53 
54                 {% if test_cases.has_next %}
55                 <a class='active' href="?page={{ test_cases.next_page_number }}">下一頁</a>
56                 {% endif %}
57             </li>
58         </ul>
59     </nav>
60 </div>
61 {% endblock %}

?

4.7 模塊頁面展示所包含用例

?

1)新增模塊頁面的用例路由配置:

?

from django.urls import path, re_path
from . import viewsurlpatterns = [path('', views.index),path('login/', views.login),path('logout/', views.logout),path('project/', views.project, name='project'),path('module/', views.module, name='module'),path('test_case/', views.test_case, name="test_case"),re_path('test_case_detail/(?P<test_case_id>[0-9]+)', views.test_case_detail, name="test_case_detail"),re_path('module_test_cases/(?P<module_id>[0-9]+)/$', views.module_test_cases, name="module_test_cases"),
]

?

2)新增視圖函數:

?

  1 from django.shortcuts import render, redirect, HttpResponse2 from django.contrib import auth  # Django用戶認證(Auth)組件一般用在用戶的登錄注冊上,用于判斷當前的用戶是否合法3 from django.contrib.auth.decorators import login_required4 from django.core.paginator import Paginator, PageNotAnInteger, InvalidPage5 from .form import UserForm6 import traceback7 from .models import Project, Module, TestCase8 9 10 # 封裝分頁處理11 def get_paginator(request, data):12     paginator = Paginator(data, 10)  # 默認每頁展示10條數據13     # 獲取 url 后面的 page 參數的值, 首頁不顯示 page 參數, 默認值是 114     page = request.GET.get('page')15     try:16         paginator_pages = paginator.page(page)17     except PageNotAnInteger:18         # 如果請求的頁數不是整數, 返回第一頁。19         paginator_pages = paginator.page(1)20     except InvalidPage:21         # 如果請求的頁數不存在, 重定向頁面22         return HttpResponse('找不到頁面的內容')23     return paginator_pages24 25 26 # 項目菜單27 @login_required28 def project(request):29     print("request.user.is_authenticated: ", request.user.is_authenticated)30     projects = Project.objects.filter().order_by('-id')31     print("projects:", projects)32     return render(request, 'project.html', {'projects': get_paginator(request, projects)})33 34 35 # 模塊菜單36 @login_required37 def module(request):38     if request.method == "GET":  # 請求get時候,id倒序查詢所有的模塊數據39         modules = Module.objects.filter().order_by('-id')40         return render(request, 'module.html', {'modules': get_paginator(request, modules)})41     else:  # 否則就是Post請求,會根據輸入內容,使用模糊的方式查找所有的項目42         proj_name = request.POST['proj_name']43         projects = Project.objects.filter(name__contains=proj_name.strip())44         projs = [proj.id for proj in projects]45         modules = Module.objects.filter(belong_project__in=projs)  # 把項目中所有的模塊都找出來46         return render(request, 'module.html', {'modules': get_paginator(request, modules), 'proj_name': proj_name})47 48 49 # 測試用例菜單50 @login_required51 def test_case(request):52     print("request.session['is_login']: {}".format(request.session['is_login']))53     test_cases = ""54     if request.method == "GET":55         test_cases = TestCase.objects.filter().order_by('id')56         print("testcases in testcase: {}".format(test_cases))57     elif request.method == "POST":58         print("request.POST: {}".format(request.POST))59         test_case_id_list = request.POST.getlist('testcases_list')60         if test_case_id_list:61             test_case_id_list.sort()62             print("test_case_id_list: {}".format(test_case_id_list))63         test_cases = TestCase.objects.filter().order_by('id')64     return render(request, 'test_case.html', {'test_cases': get_paginator(request, test_cases)})65 66 67 # 用例詳情頁68 @login_required69 def test_case_detail(request, test_case_id):70     test_case_id = int(test_case_id)71     test_case = TestCase.objects.get(id=test_case_id)72     print("test_case: {}".format(test_case))73     print("test_case.id: {}".format(test_case.id))74     print("test_case.belong_project: {}".format(test_case.belong_project))75 76     return render(request, 'test_case_detail.html', {'test_case': test_case})77 78 79 # 模塊頁展示測試用例80 @login_required81 def module_test_cases(request, module_id):82     module = ""83     if module_id:  # 訪問的時候,會從url中提取模塊的id,根據模塊id查詢到模塊數據,在模板中展現84         module = Module.objects.get(id=int(module_id))85     test_cases = TestCase.objects.filter(belong_module=module).order_by('-id')86     print("test_case in module_test_cases: {}".format(test_cases))87     return render(request, 'test_case.html', {'test_cases': get_paginator(request, test_cases)})88 89 90 # 默認頁的視圖函數91 @login_required92 def index(request):93     return render(request, 'index.html')94 95 96 # 登錄頁的視圖函數97 def login(request):98     print("request.session.items(): {}".format(request.session.items()))  # 打印session信息99     if request.session.get('is_login', None):
100         return redirect('/')
101     # 如果是表單提交行為,則進行登錄校驗
102     if request.method == "POST":
103         login_form = UserForm(request.POST)
104         message = "請檢查填寫的內容!"
105         if login_form.is_valid():
106             username = login_form.cleaned_data['username']
107             password = login_form.cleaned_data['password']
108             try:
109                 # 使用django提供的身份驗證功能
110                 user = auth.authenticate(username=username, password=password)  # 從auth_user表中匹配信息,匹配到則返回用戶對象
111                 if user is not None:
112                     print("用戶【%s】登錄成功" % username)
113                     auth.login(request, user)
114                     request.session['is_login'] = True
115                     # 登錄成功,跳轉主頁
116                     return redirect('/')
117                 else:
118                     message = "用戶名不存在或者密碼不正確!"
119             except:
120                 traceback.print_exc()
121                 message = "登錄程序出現異常"
122         # 用戶名或密碼為空,返回登錄頁和錯誤提示信息
123         else:
124             return render(request, 'login.html', locals())
125     # 不是表單提交,代表只是訪問登錄頁
126     else:
127         login_form = UserForm()
128         return render(request, 'login.html', locals())
129 
130 
131 # 注冊頁的視圖函數
132 def register(request):
133     return render(request, 'register.html')
134 
135 
136 # 登出的視圖函數:重定向至index視圖函數
137 @login_required
138 def logout(request):
139     auth.logout(request)
140     request.session.flush()
141     return redirect("/login/")

?

3)修改模塊的模板文件:在模塊名稱鏈接中,添加對應測試用例的路由地址。

?

 1 {% extends 'base.html' %}2 {% load static %}3 {% block title %}模塊{% endblock %}4 5 {% block content %}6 <form action="{% url 'module'%}" method="POST">7     {% csrf_token %}8     <input style="margin-left: 5px;" type="text" name="proj_name" value="{{ proj_name }}" placeholder="輸入項目名稱搜索模塊">9     <input type="submit" value="搜索">
10 </form>
11 
12 <div class="table-responsive">
13 
14     <table class="table table-striped">
15         <thead>
16         <tr>
17             <th>id</th>
18             <th>模塊名稱</th>
19             <th>所屬項目</th>
20             <th>測試負責人</th>
21             <th>模塊描述</th>
22             <th>創建時間</th>
23             <th>更新時間</th>
24             <th>測試結果統計</th>
25         </tr>
26         </thead>
27         <tbody>
28 
29         {% for module in modules %}
30         <tr>
31             <td>{{ module.id }}</td>
32             <td><a href="{% url 'module_test_cases' module.id %}">{{ module.name }}</a></td>
33             <td>{{ module.belong_project.name }}</td>
34             <td>{{ module.test_owner }}</td>
35             <td>{{ module.desc }}</td>
36             <td>{{ module.create_time|date:"Y-n-d H:i" }}</td>
37             <td>{{ module.update_time|date:"Y-n-d H:i" }}</td>
38             <td><a href="">查看</a></td>
39         </tr>
40         {% endfor %}
41 
42         </tbody>
43     </table>
44 </div>
45 
46 {# 實現分頁標簽的代碼 #}
47 {# 這里使用 bootstrap 渲染頁面 #}
48 <div id="pages" class="text-center">
49     <nav>
50         <ul class="pagination">
51             <li class="step-links">
52                 {% if modules.has_previous %}
53                 <a class='active' href="?page={{ modules.previous_page_number }}">上一頁</a>
54                 {% endif %}
55 
56                 <span class="current">
57                     第 {{ modules.number }} 頁 / 共 {{ modules.paginator.num_pages }} 頁</span>
58 
59                 {% if modules.has_next %}
60                 <a class='active' href="?page={{ modules.next_page_number }}">下一頁</a>
61                 {% endif %}
62             </li>
63         </ul>
64     </nav>
65 </div>
66 {% endblock %}

?

??

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/915669.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/915669.shtml
英文地址,請注明出處:http://en.pswp.cn/news/915669.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CentOS 7 配置環境變量常見的4種方式

?博客主頁&#xff1a; https://blog.csdn.net/m0_63815035?typeblog &#x1f497;《博客內容》&#xff1a;.NET、Java.測試開發、Python、Android、Go、Node、Android前端小程序等相關領域知識 &#x1f4e2;博客專欄&#xff1a; https://blog.csdn.net/m0_63815035/cat…

k8s:手動創建PV,解決postgis數據庫本地永久存儲

1.離線環境CPU:Hygon C86 7285 32-core Processor 操作系統&#xff1a;麒麟操作系統 containerd&#xff1a;1.7.27 Kubernetes:1.26.12 KubeSphere:4.1.2 kubekey&#xff1a;3.1.10 Harbor:2.13.1 Postgis:17-3.52創建StorageClass2.1創建 apiVersion: storage.k8s.io/v1kin…

谷歌瀏覽器Chrome的多用戶配置文件功能

谷歌瀏覽器Chrome的多用戶配置文件功能允許在同一設備上創建多個獨立賬戶,每個賬戶擁有完全隔離的瀏覽數據(如書簽、歷史記錄、擴展、Cookies等),非常適合工作/生活賬戶分離、家庭共享或臨時多賬號登錄場景。 如何使用Chrome的多用戶配置文件功能? 一、創建與切換用戶 1.…

傲軟錄屏 專業高清錄屏軟件 ApowerREC Pro 下載與保姆級安裝教程!!

小編今天分享一款強大的電腦屏幕錄像軟件 傲軟錄屏 ApowerREC&#xff0c;能夠幫助用戶錄制中電腦桌面屏幕上的所有內容&#xff0c;包括畫面和聲音&#xff0c;支持全屏錄制、區域錄制、畫中畫以及攝像頭錄制等多種視頻錄制模式&#xff0c;此外&#xff0c;還支持計劃任務錄制…

【計算機網絡】MAC地址與IP地址:網絡通信的雙重身份標識

在計算機網絡領域&#xff0c;MAC地址與IP地址是兩個核心概念&#xff0c;它們共同構成了數據傳輸的基礎。理解二者的區別與聯系&#xff0c;對于網絡配置、故障排查及安全管理至關重要。 一、基本概念 1. MAC地址&#xff08;物理地址&#xff09; 定義&#xff1a;固化在網絡…

如何用keepAlive實現標簽頁緩存

什么是KeepAlive首先&#xff0c;要明確所說的是TCP的 KeepAlive 還是HTTP的 Keep-Alive。TCP的KeepAlive和HTTP的Keep-Alive是完全不同的概念&#xff0c;不能混為一談。實際上HTTP的KeepAlive寫法是Keep-Alive&#xff0c;跟TCP的KeepAlive寫法上也有不同。TCP的KeepAliveTCP…

數據庫隔離級別

隔離級別決定了事務之間的可見性規則&#xff0c;直接影響數據庫的并發性能和數據一致性。SQL 標準定義了 4 種隔離級別&#xff0c;從低到高依次為&#xff1a;讀未提交→讀已提交→可重復讀→串行化。隔離級別越高&#xff0c;對并發問題的解決能力越強&#xff0c;但對性能的…

基于Python flask的電影數據分析及可視化系統的設計與實現,可視化內容很豐富

摘要&#xff1a;基于Python的電影數據分析及可視化系統是一個應用于電影市場的數據分析平臺&#xff0c;旨在為廣大電影愛好者提供更準確、更詳細、更實用的電影數據。數據分析部分主要是對來自貓眼電影網站上的數據進行清洗、分類處理、存儲等步驟&#xff0c;數據可視化則是…

TCP通訊開發注意事項及常見問題解析

文章目錄一、TCP協議特性與開發挑戰二、粘包與拆包問題深度解析1. 成因原理2. 典型場景與實例驗證3. 系統化解決方案接收方每次讀取10字節2. 丟包檢測與驗證工具3. 工程化解決方案四、連接管理關鍵實踐1. 超時機制設計2. TIME_WAIT狀態優化3. 異常處理最佳實踐五、高性能TCP開發…

2021 RoboCom 世界機器人開發者大賽-本科組(復賽)解題報告 | 珂學家

前言 題解 睿抗機器人開發者大賽CAIP-編程技能賽-歷年真題 匯總 2021 RoboCom 世界機器人開發者大賽-本科組&#xff08;復賽&#xff09;解題報告 感覺這個T1特別有意思&#xff0c;非典型題&#xff0c;著重推演下結論。 T2是一道玄學題&#xff0c;但是涉及一些優化技巧…

《計算機“十萬個為什么”》之 MQ

《計算機“十萬個為什么”》之 MQ &#x1f4e8; 歡迎來到消息隊列的奇妙世界&#xff01; 在這篇文章中&#xff0c;我們將探索 MQ 的奧秘&#xff0c;從基礎概念到實際應用&#xff0c;讓你徹底搞懂這個分布式系統中不可或缺的重要組件&#xff01;&#x1f680; 作者&#x…

Django母嬰商城項目實踐(七)- 首頁數據業務視圖

7、首頁數據業務視圖 1、介紹 視圖(View)是Django的MTV架構模式的V部分,主要負責處理用戶請求和生成相應的響應內容,然后在頁面或其他類型文檔中顯示。 也可以理解為視圖是MVC架構里面的C部分(控制器),主要處理功能和業務上的邏輯。我們習慣使用視圖函數處理HTTP請求,…

android 12 的 aidl for HAL 開發示例

說明&#xff1a;aidl for HAL 這種機制&#xff0c;可以自動生成java代碼&#xff0c;app調用可以獲取中間過程的jar包&#xff0c;結合反射調用 ServiceManager.getService 方法&#xff0c;直接獲取 HAL 服務&#xff0c;不再需要費力在framework層添加代碼&#xff0c;方便…

網絡安全滲透攻擊案例實戰:某公司內網為目標的滲透測試全過程

目錄一、案例背景二、目標分析&#xff08;信息收集階段&#xff09;&#x1f310; 外部信息搜集&#x1f9e0; 指紋識別和端口掃描三、攻擊流程&#xff08;滲透測試全過程&#xff09;&#x1f3af; 步驟1&#xff1a;Web漏洞利用 —— 泛微OA遠程命令執行漏洞&#xff08;CV…

AI視頻-劇本篇學習筆記

1.提示詞萬能框架是什么:ai扮演的角色做什么&#xff1a;解決什么問題怎么做&#xff1a;標準2、劇本模版假設你是一位擁有30年電影拍攝經驗的世界頂級導演&#xff0c;擁有豐富的電影拍攝經驗和高超的電影拍攝技術&#xff0c;同時也擅長各種影片的劇本創作。我需要你仔細閱讀…

A316-HF-DAC-V1:專業USB HiFi音頻解碼器評估板技術解析

引言 隨著高解析度音頻的普及&#xff0c;對高品質音頻解碼設備的需求日益增長。本文將介紹一款專為USB HiFi音頻解碼器設計的專業評估板——A316-HF-DAC-V1&#xff0c;這是一款基于XMOS XU316技術的高性能音頻解碼評估平臺。產品概述 A316-HF-DAC-V1是一款專業的USB HiFi音頻…

超低延遲RTSP播放器在工業機器人遠程控制中的應用探索

技術背景 在智能制造高速發展的今天&#xff0c;工業機器人已經從單一的生產作業工具&#xff0c;轉變為協作化、智能化的生產伙伴。無論是高精度的多關節機械臂、自主導航的移動機器人&#xff0c;還是與人協同工作的協作機器人&#xff0c;都越來越多地被應用于智能工廠、倉…

Elasticsearch Java 8.x 的聚合 API 及子聚合的用法

背景 Elasticsearch 版本發布的很勤&#xff0c; API 客戶端的用法各個版本之間差異也是很大。尤其是 Elasticsearch 8.x 版本直接廢棄了 RestHighLevelClient 對象。 Query 和 Aggregation 的 Builder 的用法也有變化。 本文記錄項目升級 Elasticsearch API 到 8.x 版本時聚合…

Dify功能熟悉

Dify功能熟悉 文章目錄Dify功能熟悉一、介紹1.1 快速開始1.2 官方文檔二、workflow2.1 開始和結束2.2 簡單示例三、節點3.1 節點一覽表3.2 節點-----開始3.3 節點-----LLM3.4 知識檢索&#xff08;增強回答準確性&#xff09;3.5 Agent智能體3.6 問題分類器3.7 http四、工具&am…

app引導頁設計要點與交互細節詳解

在移動應用的設計中&#xff0c;用戶第一次打開APP時看到的往往就是app引導頁。它不僅是品牌與用戶接觸的第一道界面&#xff0c;也是決定用戶是否愿意繼續探索的關鍵入口。一個設計合理、信息傳達清晰的app引導頁&#xff0c;能夠幫助產品建立專業感與品牌價值&#xff0c;同時…