面是一個使用Django框架搭建自動化測試平臺的基本教程。我們將創建一個簡單的自動化測試平臺,它能夠接收用戶的測試用例提交、執行這些測試用例,并返回測試結果。
確保你已經安裝了Python。然后,在命令行中安裝Django:
Bash
深色版本
1pip install django
創建一個新的Django項目:
Bash
深色版本
1django-admin startproject test_platform
2cd test_platform
創建一個名為tests的應用:
Bash
深色版本
1python manage.py startapp tests
編輯test_platform/urls.py文件,將新的應用添加到URL配置中:
Python
深色版本
1from django.contrib import admin
2from django.urls import path, include
3
4urlpatterns=[
5 path('admin/', admin.site.urls),
6 path('', include('tests.urls')),
7]
在tests應用中創建urls.py文件:
Python
深色版本
1from django.urls import path
2from . import views
3
4urlpatterns=[
5 path('', views.index, name='index'),
6 path('submit_test/', views.submit_test, name='submit_test'),
7 path('results/<int:test_id>/', views.results, name='results'),
8]
在tests/views.py文件中編寫視圖函數:
Python
深色版本
1from django.shortcuts import render, redirect, get_object_or_404
2from .forms import TestForm
3from .models import Test
4from django.http import HttpResponse
5from django.core.files.storage import FileSystemStorage
6
7def index(request):
8 return render(request, 'tests/index.html')
9
10def submit_test(request):
11 if request.method=='POST':
12 form=TestForm(request.POST, request.FILES)
13 if form.is_valid():
14 test=form.save()
15 # 在這里可以調用腳本來執行測試
16 return redirect('results', test_id=test.id)
17 else:
18 form=TestForm()
19 return render(request, 'tests/submit_test.html', {'form': form})
20
21def results(request, test_id):
22 test=get_object_or_404(Test, pk=test_id)
23 # 從數據庫或其他地方獲取測試結果
24 return render(request, 'tests/results.html', {'test': test})
在tests/models.py文件中定義模型:
Python
深色版本
1from django.db import models
2
3class Test(models.Model):
4 name=models.CharField(max_length=200)
5 description=models.TextField()
6 file=models.FileField(upload_to='uploads/')
7 created_at=models.DateTimeField(auto_now_add=True)
8
9 def __str__(self):
10 return self.name
在tests/forms.py文件中定義表單:
Python
深色版本
1from django import forms
2from .models import Test
3
4class TestForm(forms.ModelForm):
5 class Meta:
6 model=Test
7 fields=['name', 'description', 'file']
在tests/templates/tests目錄下創建模板文件:
例如,submit_test.html可以這樣創建:
Html
深色版本
1{% extends 'base.html' %}
2
3{% block content %}
4<h1>Submit a New Test</h1>
5<form method="post" enctype="multipart/form-data">
6 {% csrf_token %}
7 {{ form.as_p }}
8 <button type="submit">Submit Test</button>
9</form>
10{% endblock %}
運行以下命令創建數據庫表:
Bash
深色版本
1python manage.py makemigrations
2python manage.py migrate
在項目目錄下創建static和media文件夾。然后在settings.py中添加以下設置:
Python
深色版本
1STATIC_URL='/static/'
2MEDIA_URL='/media/'
3MEDIA_ROOT=os.path.join(BASE_DIR, 'media')
啟動開發服務器:
Bash
深色版本
1python manage.py runserver
在視圖函數submit_test中,你可以添加代碼來執行自動化測試腳本。這通常涉及讀取用戶上傳的文件,解析測試用例,并使用如unittest或pytest這樣的測試框架來運行測試。
例如,你可以在submit_test函數中添加如下代碼來執行測試腳本:
Python
深色版本
1import subprocess
2
3def execute_test_script(file_path):
4 # 假設測試腳本是一個可執行的Python腳本
5 try:
6 output=subprocess.check_output(['python', file_path], stderr=subprocess.STDOUT)
7 # 將輸出保存到數據庫或返回給用戶
8 return output.decode('utf-8')
9 except subprocess.CalledProcessError as e:
10 # 處理錯誤情況
11 return e.output.decode('utf-8')
一旦完成開發和測試,你可以考慮將應用部署到生產環境。可以選擇使用如Heroku、Docker、AWS等服務進行部署。
以上是從零開始使用Django框架搭建自動化測試平臺的基本步驟。你可以根據實際需求進一步完善功能,例如增加用戶認證、測試報告生成、郵件通知等功能。希望這份指南對你有所幫助!
一篇:Python之Django系列-創建第一個應用-5
我們接著上一篇開始,這一篇我們主要會講到投票視圖以及最終投票結果視圖,我們先修改上一篇有說到的polls/templates/polls/detail.html頁面,讓用戶跳轉到這個界面時可以選擇任意一項進行投票,修改后最終代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>問題詳情頁</title>
</head>
<body>
<h1>{{ question.question_text }}</h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
{% for choice in question.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>
{% endfor %}
<input type="submit" value="投票">
</form>
</body>
</html>
代碼講解
polls/urls.py
這個頁面修改成功后,目前數據庫中的django_question表和django_choice表的數據截圖如下:
django_question(問題表)
django_choice(投票記錄表)
我們啟動服務,打開瀏覽器http://127.0.0.1:8000/polls/1/,可以看到簡單的投票頁面
投票詳情頁面
當polls/templates/polls/detail.html頁面完善后,打開頁面看到上圖,但是我們點投票的時候并沒有做視圖相關的業務處理,我們看看detail.html中submit提交的接口為{% url 'polls:vote' question.id %}這個翻譯過來假如question.id=1那么這個地址就是/polls/1/vote,但是我們vote視圖處理目前還是如下代碼
def vote(request, question_id):
return HttpResponse("進行投票 %s." % question_id)
并沒有實現投票的業務邏輯,現在我們稍微來改造下這個方法如下
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
from .models import Question, Choice
# ...為了讓文章篇幅更短,此處省略其他方法
def vote(request, question_id):
question=get_object_or_404(Question, pk=question_id)
try:
selected_choice=question.choice_set.get(pk=request.POST['choice'])
except(KeyError, Choice.DoesNotExist):
return render(request, 'polls/detail.html', {'question': question, 'error_message': '你沒有選擇一個選項'})
else:
selected_choice.votes +=1
selected_choice.save()
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
代碼講解
404
說到這里,我們就還需要編輯重定向后的視圖以及界面,重定向后的視圖編碼為
更改前:
#問題結果頁
def results(request, question_id):
return HttpResponse("查看問題的結果 %s." % question_id)
更改后:
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
from .models import Question, Choice
# ...為了讓文章篇幅更短,此處省略其他方法
def results(request, question_id):
question=get_object_or_404(Question, pk=question_id)
return render(request, 'polls/results.html', {'question': question})
我們還需要新增polls/templates/polls/results.html界面,如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>投票結果</title>
</head>
<body>
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
{% endfor %}
</ul>
<a href="{% url 'polls:detail' question.id %}">再次投票?</a>
</body>
</html>
編輯完成后,現在我們打開地址:http://127.0.0.1:8000/polls/1/ 選擇任意一個選項,點擊"投票"按鈕,就會展示如下結果:
點擊再次投票,再跳轉到投票詳情頁面,反復執行,將會看到投票數的變化
在使用通用視圖之前,我們先了解下通用視圖的定義,通用意思是重復用,避免重復造輪子,通用視圖旨在將常見的模式抽象化,可以使你在編寫應用時甚至不需要編寫Python代碼。
既然說是通用視圖,那么我們先來改造視圖,先直接貼出最終代碼:
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
from django.views import generic
from .models import Question, Choice
# Create your views here.
class IndexView(generic.ListView):
template_name='polls/index.html'
context_object_name='latest_question_list'
def get_queryset(self):
return Question.objects.order_by("-pub_date")[:5]
class DetailView(generic.DetailView):
model=Question
template_name='polls/detail.html'
class ResultsView(generic.DetailView):
model=Question
template_name='polls/results.html'
def vote(request, question_id):
question=get_object_or_404(Question, pk=question_id)
try:
selected_choice=question.choice_set.get(pk=request.POST['choice'])
except(KeyError, Choice.DoesNotExist):
return render(request, 'polls/detail.html', {'question': question, 'error_message': '你沒有選擇一個選項'})
else:
selected_choice.votes +=1
selected_choice.save()
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
我們會看到index(),detail(),results()方法已經都被刪除,而新增的有類IndexView,DetailView,ResultsView,下面我們來講講這些變化的地方
新增類IndexView繼承generic.ListView,其中屬性template_name,context_object_name都進行重寫,默認情況下ListView會生成模板<app_name>/<model_name>_list.html,app_name則是我們URLconf(polls/urls.py文件)中的變量,mode_name則是Question,那么默認的模板名字則是"polls/question_list.html",而我們重寫template_name值,則會直接拿重寫后的值也就是"polls/index.html",而context_object_name我們需要重寫則是因為我們html模板需要用到該屬性,以免報錯
DetailView和ResultsView我就挑DetailView描述下,兩個實現原理其實都差不多,這個需要結合改造后的URLconf(polls/url.py)來講,URLconf改造如下:
改造前:
from django.urls import path
from . import views
app_name='polls'
urlpatterns=[
path('', views.index, name='index'),#問題列表頁
path('<int:question_id>/', views.detail, name='detail'),#問題詳情頁
path('<int:question_id>/results/', views.results, name='results'),#問題結果頁
path('<int:question_id>/vote/', views.vote, name='vote'),#投票處理器
]
改造后:
from django.urls import path
from . import views
app_name='polls'
urlpatterns=[
path('', views.IndexView.as_view(), name='index'),#問題列表頁
path('<int:pk>/', views.DetailView.as_view(), name='detail'),#問題詳情頁
path('<int:pk>/results/', views.ResultsView.as_view(), name='results'),#問題結果頁
path('<int:question_id>/vote/', views.vote, name='vote'),#投票處理器
]
其中列表頁,詳情頁,結果頁都已經更改,question_id更改為pk,而這個pk則代表數據庫表的主鍵ID,當我們訪問詳情頁(DetailView)時,傳入主鍵ID,模板就能渲染相關數據,而DetailView的父類generic.DetailView默認的模板地址生成為<app_name>/<model_name>_detail.html,那么就可能變成"polls/question_detail.html",但是該模板頁面我們并沒有開發,所以我們重寫了model以及template_name屬性,最終會生成為"polls/detail.html"
現在讓我們重新打開http://127.0.0.1:8000/polls/1/看看通用視圖是否生效吧
下一篇:Python之Django系列-創建第一個應用-7
構建功能完備且用戶體驗良好的Web應用時,表單驗證是一個不可或缺的部分。本文將深入探討如何使用 Flask 框架集成的 flask-wtf 庫實現網頁表單驗證,并提供詳細的代碼示例以助您快速掌握這一實用技能。
flask-wtf 是 Flask 用于處理 Web 表單的一個擴展庫,它基于 wtforms 庫,提供了便捷的方式來創建和驗證 HTML 表單。通過 Flask-wtf,您可以輕松定義表單字段、編寫驗證規則并處理提交的數據。
首先確保已安裝 flask-wtf:
pip install Flask-WTF
在 Flask 應用中引入并初始化 flask-wtf:
from flask import Flask
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length, EqualTo
app=Flask(__name__)
app.config['SECRET_KEY']='your-secret-key' # 設置一個安全密鑰用于表單驗證
下面是一個用戶注冊表單的示例,包含用戶名、密碼以及確認密碼字段,其中包含了數據必填性、長度限制以及密碼匹配等驗證規則:
class RegistrationForm(FlaskForm):
username=StringField('用戶名', validators=[DataRequired(), Length(min=2, max=20)])
password=PasswordField('密碼', validators=[DataRequired()])
confirm_password=PasswordField('確認密碼',
validators=[DataRequired(), EqualTo('password', message='兩次密碼不一致')])
submit=SubmitField('Sign Up')
在視圖函數中,我們可以實例化表單對象,渲染表單至模板,并處理表單提交后的驗證結果:
@app.route('/register', methods=['GET', 'POST'])
def register():
form=RegistrationForm()
if form.validate_on_submit(): # 驗證表單數據
# 這里是處理有效表單數據的邏輯,例如保存到數據庫
flash('用戶注冊成功!', 'success')
return redirect(url_for('index'))
return render_template('register.html', title='Register', form=form)
在 Jinja2 模板文件(如 templates/register.html)中,我們可以渲染表單:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>用戶注冊</h1>
<form method="POST" action="{{ url_for('register') }}">
{{ form.csrf_token }} <!-- 添加CSRF令牌 -->
<div>
{{ form.username.label }}<br>
{{ form.username(size=20) }}
</div>
<div>
{{ form.password.label }}<br>
{{ form.password() }}
</div>
<div>
{{ form.confirm_password.label }}<br>
{{ form.confirm_password() }}
</div>
<div>
{{ form.submit() }}
</div>
</form>
</body>
</html>
通過以上步驟,我們成功地在 Flask 應用中使用了 flask-wtf 實現了一個具有驗證功能的用戶注冊表單。
當表單驗證失敗時(form.validate_on_submit()返回False),flask-wtf會將驗證錯誤信息存儲在表單對象中。我們可以在模板中遍歷這些錯誤并顯示給用戶:
<!-- 在templates/register.html中添加錯誤信息顯示 -->
{% for field, errors in form.errors.items() %}
{% for error in errors %}
<p style="color: red;">{{ form[field].label }}: {{ error }}</p>
{% endfor %}
{% endfor %}
在某些情況下,您可能需要為特定字段或驗證器提供自定義錯誤消息。這可以通過在定義表單類時直接指定驗證器的message參數來實現:
from wtforms import ValidationError
class RegistrationForm(FlaskForm):
# ...
def validate_username(self, username_field):
if User.query.filter_by(username=username_field.data).first():
raise ValidationError('Username already exists. Please choose another one.')
通過flask-wtf,我們可以高效且規范地管理Web應用中的表單驗證和數據處理流程。結合wtforms強大的驗證器庫,您可以根據需求創建各種復雜度的表單,并確保用戶的輸入滿足預設的業務規則。
實踐是檢驗真理的唯一標準,鼓勵各位讀者在實際項目開發中嘗試運用flask-wtf進行表單驗證,不斷優化和完善代碼邏輯,從而提升Python Web開發的能力和效率。
關注我,手把手帶你快速入門Python Web編程!
*請認真填寫需求信息,我們會在24小時內與您取得聯系。