[TOC]
## **一、概述**
Django 中的視圖的概念是一類具有相同功能和模板的網頁的集合。一個視圖通常對應一個頁面,提供特定的功能,使用特定的模板。例如:在一個博客應用中,你可能會看到下列視圖:
* 博客主頁:顯示最新發布的一些內容
* 每篇博客的詳細頁面:顯示博客的詳細內容
* 基于年的博客頁面:顯示指定年內的所有博客文章
* 基于月的博客頁面:顯示指定月內的所有博客文章
* 基于天的博客頁面:顯示指定日內的所有博客文章
* 發布評論:處理針對某篇博客發布的評論
在我們的投票應用中,我們將建立下面的視圖:
* 問卷“index”頁:顯示最新的一些問卷
* 問卷“detail”頁面:顯示一個問卷的詳細文本內容,沒有調查結果但是有一個投票或調查表單。
* 問卷“results”頁面:顯示某個問卷的投票或調查結果。
* 投票動作頁面:處理針對某個問卷的某個選項的投票動作。
<br />
在Django中,網頁和其它的一些內容都是通過視圖來處理的。視圖其實就是一個簡單的Python函數(在基于類的視圖中稱為方法)。Django通過對比請求的URL地址來選擇對應的視圖,也就是路由。
<br />
在你上網的過程中,很可能看見過像這樣的丑陋的URL: "ME2/Sites/dirmod.asp?sid=&type=gen&mod=Core+Pages&gid=A6CD4967199A42D9B65B1B" 。別擔心,Django 里的 URL規則要比這優雅的多!比如:`/newsarchive/<year>/<month>/`。
為了將 URL 和視圖關聯起來,Django 使用`URLconfs`來配置路由。
<br />
## **二、編寫視圖**
下面,打開`polls/views.py`文件,輸入下列代碼:
~~~
# 注意函數的參數
def detail(request, question_id):
return HttpResponse("You're looking at question %s." % question_id)
def results(request, question_id):
response = "You're looking at the results of question %s."
return HttpResponse(response % question_id)
def vote(request, question_id):
return HttpResponse("You're voting on question %s." % question_id)
~~~
然后,在`polls/urls.py`文件中加入下面的路由,將其映射到我們上面新增的視圖。
~~~
from django.urls import path
from . import views
urlpatterns = [
# 例如: /polls/
path('', views.index, name='index'),
# 例如: /polls/5/
path('<int:question_id>/', views.detail, name='detail'),
# 例如: /polls/5/results/
path('<int:question_id>/results/', views.results, name='results'),
# 例如: /polls/5/vote/
path('<int:question_id>/vote/', views.vote, name='vote'),
]
~~~
現在去瀏覽器中訪問`/polls/34/`(注意:這里省略了域名。另外,使用了二級路由后,url中都要添加字符串`polls`前綴,參考前面的章節),它將調用`detail()`函數,然后在頁面中顯示你在url里提供的ID。訪問`/polls/34/results/`和`/polls/34/vote/`,將分別顯示預定義的偽結果和投票頁面。(PS:這里就不貼圖了,請大家務必自己動手測試,多實踐。切記不要輸入錯誤!)
<br />
上面訪問的路由過程如下:當有人訪問`/polls/34/`地址時,Django將首先加載`mysite.urls`模塊,因為它是settings文件里設置的根URL配置文件。在該文件里,Django發現了`urlpatterns`變量,于是在其內按順序進行匹配。當它匹配上了`polls/`,就裁去url中匹配的文本`polls/`,然后將剩下的文本“`34/`”,傳遞給`polls.urls`進行下一步的處理。在`polls.urls`中,又匹配到了`<int:question_id>/`,最終結果就是調用該模式對應的detail視圖,也就是下面的函數:
~~~
detail(request=<HttpRequest object>, question_id=34)
~~~
函數中的`question_id=’34’`參數,是由`<int:question_id>/`而來。使用尖括號“捕獲”這部分 URL,且以關鍵字參數的形式發送給視圖函數。上述字符串的`question_id`部分定義了將被用于區分匹配模式的變量名,而`int`則是一個轉換器決定了應該以什么變量類型匹配這部分的 URL 路徑。
不要書寫類似下面的較為愚蠢的包含`.html`的模式,它顯然是沒必要,不夠簡練的:
~~~
path('polls/latest.html', views.index),
~~~
<br />
## **三、編寫能實際干點活的視圖**
每個視圖至少做兩件事之一:返回一個包含請求頁面的HttpResponse對象或者彈出一個類似Http404的異常。其它的則隨你便,你愛干嘛干嘛。
<br />
下面是一個新的index視圖,用于替代先前無用的index,它會根據發布日期顯示最近的5個投票問卷。
~~~
from django.http import HttpResponse
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
output = ', '.join([q.question_text for q in latest_question_list])
return HttpResponse(output)
# 省略了那些沒改動過的視圖(detail, results, vote)
~~~
**這里有個非常重要的問題:在當前視圖中的HTML頁面是硬編碼的。** 如果你想改變頁面的顯示內容,就必須修改這里的Python代碼。為了解決這個問題,需要使用Django提供的模板系統,解耦視圖和模板之間的硬連接。
<br />
首先,在`polls`目錄下創建一個新的`templates`目錄,Django會在它里面查找模板文件。
<br />
項目`settings.py`文件中的`TEMPLATES`配置項描述了 Django 如何載入和渲染模板。默認的設置文件設置了`DjangoTemplates`后端作為模板引擎,并將`APP_DIRS`設置成了 True。這一選項將會讓`DjangoTemplates`在每個`INSTALLED_APPS`文件夾中尋找 "`templates`" 子目錄。
<br />
在剛才創建的`templates`目錄中,再創建一個新的子目錄名叫`polls`,進入該子目錄,創建一個新的HTML文件`index.html`。換句話說,你的模板文件應該是`polls/templates/polls/index.html`。因為 Django 會尋找到對應的`app_directories`,所以你只需要使用`polls/index.html`就可以引用到這一模板了。
<br />
**模板命名空間:**
你也許會想,為什么不把模板文件直接放在`polls/templates`目錄下,而是費勁的再建個子目錄polls呢?設想這么個情況,有另外一個app,它也有一個名叫`index.html`的文件,當Django在搜索模板時,有可能就找到它,然后退出搜索,這就命中了錯誤的目標,不是我們想要的結果。解決這個問題的最好辦法就是在templates目錄下再建立一個與app同名的子目錄,將自己所屬的模板都放到里面,從而達到獨立命名空間的作用,不會再出現引用錯誤。
現在,將下列代碼寫入文件`polls/templates/polls/index.html`:
~~~
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
~~~
為了讓教程看起來不那么長,所有的模板文件都只寫出了核心代碼。在你自己創建的項目中,你應該使用 完整的 HTML 文檔,比如:
~~~
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
</body>
</html>
~~~
同時,修改視圖文件`polls/views.py`,讓新的`index.html`文件生效:
~~~
from django.http import HttpResponse
from django.template import loader
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
template = loader.get_template('polls/index.html')
context = {
'latest_question_list': latest_question_list,
}
return HttpResponse(template.render(context, request))
~~~
上面的代碼會加載`polls/index.html`文件,并傳遞給它一個參數。這個參數是一個字典,包含了模板變量名和Python對象之間的映射關系。
<br />
在瀏覽器中通過訪問`/polls/`,你可以看到一個列表,包含`“What’s up”`的問卷,以及連接到其對應詳細內容頁面的鏈接點。
<br />
注意:如果你顯示的是`No polls are available.`說明你前面沒有添加Questions對象。前面的大量手動API操作你沒有做。沒關系,我們在admin中追加對象就可以。
<br />
**快捷方式:render()**
<br />
在實際運用中,加載模板、傳遞參數,返回HttpResponse對象是一整套再常見不過的操作了,為了節省力氣,Django提供了一個快捷方式:render函數,一步到位!
將`polls/views.py`中的index修改成下面的代碼:
~~~
from django.shortcuts import render
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
context = {'latest_question_list': latest_question_list}
return render(request, 'polls/index.html', context)
~~~
注意,我們不再需要導入`loader`,而是從`django.shortcuts`導入了render。
<br />
render()函數的第一個位置參數是請求對象(就是view函數的第一個參數),這個參數是固定寫法,不需要變動。第二個位置參數是模板文件。還可以有一個可選的第三參數,一個字典,包含需要傳遞給模板的數據。最后render函數返回一個經過字典數據渲染過的模板封裝而成的HttpResponse對象。
<br />
## **四、返回404錯誤**
現在讓我們來編寫返回具體問卷文本內容的視圖:
~~~
# polls/views.py
from django.http import Http404
from django.shortcuts import render
from .models import Question
# ...
def detail(request, question_id):
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
raise Http404("Question does not exist")
return render(request, 'polls/detail.html', {'question': question})
~~~
這里有個新知識點,如果請求的問卷ID不存在,那么會彈出一個Http404錯誤。
如果你想試試上面這段代碼是否正常工作的話,你可以新建`polls/detail.html`文件,暫時寫入下面的代碼:
~~~
{{ question }}
~~~
<br />
**快捷方式:get_object_or_404()**
就像render函數一樣,Django同樣為你提供了一個偷懶的方式,替代上面的多行代碼,那就是`get_object_or_404()`方法,參考下面的代碼:
polls/views.py
~~~
from django.shortcuts import get_object_or_404, render
from .models import Question
# ...
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question': question})
~~~
別說我沒提醒你,和render一樣,也需要從Django內置的快捷方式模塊中導出`get_object_or_404()`!
<br />
`get_object_or_404()`方法將一個Django模型作為第一個位置參數,后面可以跟上任意數量的關鍵字參數,如果對象不存在則彈出Http404錯誤。
<br />
同樣,還有一個`get_list_or_404()`方法,和上面的`get_object_or_404()`類似,只不過是用來替代`filter()`函數,當查詢列表為空時彈出404錯誤。(filter是模型API中用來過濾查詢結果的函數,它的結果是一個列表集。而get則是查詢一個結果的方法,和filter是一個和多個的區別!)
<br />
為什么我們使用輔助函數`get_object_or_404()`而不是自己捕獲`ObjectDoesNotExist`異常呢?還有,為什么模型 API 不直接拋出`ObjectDoesNotExist`而是拋出`Http404`呢?因為這樣做會增加模型層和視圖層的耦合性。指導 Django 設計的最重要的思想之一就是要保證松散耦合。一些受控的耦合將會被包含在`django.shortcuts`模塊中。
<br />
## **五、 使用模板系統**
回過頭去看看我們的 detail視圖。它向模板傳遞了上下文變量 question 。下面是 polls/detail.html 模板里正式的代碼:
~~~
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>
~~~
<br />
在模板系統中圓點`.`是萬能的魔法師,你可以用它訪問對象的屬性。在例子`{{ question.question_text }}`中,Django首先會在question對象中嘗試查找一個字典,如果失敗,則嘗試查找屬性,如果再失敗,則嘗試作為列表的索引進行查詢。
<br />
在`{% for %}`循環中的方法調用——`question.choice_set.all`其實就是Python的代碼`question.choice_set.all()`,它將返回一組可迭代的`Choice`對象,并用在`{% for %}`標簽中。
<br />
這里我們對Django模板語言有個簡單的印象就好,更深入的介紹放在后面。
<br />
## **六、刪除模板中硬編碼的URLs**
在`polls/index.html`文件中,還有一部分硬編碼存在,也就是`href`里的“/polls/”部分:
~~~
<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
~~~
它對于代碼修改非常不利。設想如果你在urls.py文件里修改了路由表達式,那么你所有的模板中對這個url的引用都需要修改,這是無法接受的!
我們前面給urls定義了一個name別名,可以用它來解決這個問題。具體代碼如下:
~~~
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
~~~
Django會在`polls.urls`文件中查找`name='detail'`的路由,具體的就是下面這行:
~~~
path('<int:question_id>/', views.detail, name='detail'),
~~~
舉個栗子,如果你想將polls的detail視圖的URL更換為`polls/specifics/12/`,那么你不需要在模板中重新修改url地址了,僅僅只需要在`polls/urls.py`文件中,將對應的正則表達式改成下面這樣的就行了,所有模板中對它的引用都會自動修改成新的鏈接:
~~~
# 添加新的單詞'specifics'
path('specifics/<int:question_id>/', views.detail, name='detail'),
~~~
<br />
## **七、URL names的命名空間**
本教程例子中,只有一個app,也就是polls,但是在現實中很顯然會有5個、10個、更多的app同時存在一個項目中。Django是如何區分這些app之間的URL name呢?舉個例子,`polls`應用有`detail`視圖,可能另一個博客應用也有同名的視圖。Django 如何知道`{% url %}`標簽到底對應哪一個應用的 URL 呢?
<br />
**答案是使用URLconf的命名空間。** 可以在polls/urls.py文件的開頭部分,添加一個`app_name`的變量來指定該應用的命名空間:
~~~
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'),
]
~~~
現在,讓我們將代碼修改得更嚴謹一點,將`polls/templates/polls/index.html`中的
~~~
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
~~~
修改為:
~~~
<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
~~~
**注意引用方法是冒號,不是圓點也不是斜杠!**
- Linux
- Linux 文件權限概念
- 重點總結
- Linux 文件與目錄管理
- 2.1 文件與目錄管理
- 2.2 文件內容查閱
- 文件與文件系統的壓縮,打包與備份
- 3.1 Linux 系統常見的壓縮指令
- 3.2 打包指令: tar
- vi/vim 程序編輯器
- 4.1 vi 的使用
- 4.2 vim編輯器刪除一行或者多行內容
- 進程管理
- 5.1 常用命令使用技巧
- 5.2 進程管理
- 系統服務 (daemons)
- 6.1 通過 systemctl 管理服務
- Linux 系統目錄結構
- Linux yum命令
- linux系統查看、修改、更新系統時間(自動同步網絡時間)
- top linux下的任務管理器
- Linux基本配置
- CentOS7開啟防火墻
- CentOS 使用yum安裝 pip
- strace 命令
- Linux下設置固定IP地址
- 查看Linux磁盤及內存占用情況
- Mysql
- 關系數據庫概述
- 數據庫技術
- 數據庫基礎語句
- 查詢語句(--重點--)
- 約束
- 嵌套查詢(子查詢)
- 表emp
- MySQL數據庫練習
- 01.MySQL數據庫練習數據
- 02.MySQL數據庫練習題目
- 03.MySQL數據庫練習-答案
- Mysql遠程連接數據庫
- Python
- python基礎
- Python3中字符串、列表、數組的轉換方法
- python字符串
- python安裝、pip基本用法、變量、輸入輸出、流程控制、循環
- 運算符及優先級、數據類型及常用操作、深淺拷貝
- 虛擬環境(virtualenv)
- 網絡編程
- TCP/IP簡介
- TCP編程
- UDP編程
- 進程和線程
- 訪問數據庫
- 使用SQLite
- 使用MySQL
- Web開發
- HTML簡介
- Python之日志處理(logging模塊)
- 函數式編程
- 高階函數
- python報錯解決
- 啟動Python時報“ImportError: No module named site”錯誤
- python實例
- 01- 用python解決數學題
- 02- 冒泡排序
- 03- 郵件發送(smtplib)
- Django
- 01 Web應用
- Django3.2 教程
- Django簡介
- Django環境安裝
- 第一個Django應用
- Part 1:請求與響應
- Part 2:模型與后臺
- Part 3:視圖和模板
- Part 4:表單和類視圖
- Part 5:測試
- Part 6:靜態文件
- Part 7:自定義admin
- 第一章:模型層
- 實戰一:基于Django3.2可重用登錄與注冊系統
- 1. 搭建項目環境
- 2. 設計數據模型
- 3. admin后臺
- 4. url路由和視圖
- 5. 前端頁面設計
- 6. 登錄視圖
- 7. Django表單
- 8. 圖片驗證碼
- 9. session會話
- 10. 注冊視圖
- 實戰二:Django3.2之CMDB資產管理系統
- 1.項目需求分析
- 2.模型設計
- 3.數據收集客戶端
- 4.收集Windows數據
- 5.Linux下收集數據
- 6.新資產待審批區
- 7.審批新資產
- django 快速搭建blog
- imooc-Django全棧項目開發實戰
- redis
- 1.1 Redis簡介
- 1.2 安裝
- 1.3 配置
- 1.4 服務端和客戶端命令
- 1.5 Redis命令
- 1.5.1 Redis命令
- 1.5.2 鍵(Key)
- 1.5.3 字符串(string)
- 1.5.4 哈希(Hash)
- 1.5.5 列表(list)
- 1.5.6 集合(set)
- 1.5.7 有序集合(sorted set)
- Windows
- Win10安裝Ubuntu子系統
- win10遠程桌面身份驗證錯誤,要求的函數不受支持
- hm軟件測試
- 02 linux基本命令
- Linux終端命令格式
- Linux基本命令(一)
- Linux基本命令(二)
- 02 數據庫
- 數據庫簡介
- 基本概念
- Navicat使用
- SQL語言
- 高級
- 03 深入了解軟件測試
- day01
- 04 python基礎
- 語言基礎
- 程序中的變量
- 程序的輸出
- 程序中的運算符
- 數據類型基礎
- 數據序列
- 數據類型分類
- 字符串
- 列表
- 元組
- 字典
- 列表與元組的區別詳解
- 函數
- 案例綜合應用
- 列表推導式
- 名片管理系統
- 文件操作
- 面向對象基礎(一)
- 面向對象基礎(二)
- 異常、模塊
- 05 web自動化測試
- Day01
- Day02
- Day03
- Day04
- Day05
- Day06
- Day07
- Day08
- 06 接口自動化測試
- 軟件測試面試大全2020
- 第一章 測試理論
- 軟件測試面試
- 一、軟件基礎知識
- 二、網絡基礎知識
- 三、數據庫
- SQL學生表 — 1
- SQL學生表 — 2
- SQL查詢 — 3
- SQL經典面試題 — 4
- 四、linux
- a. linux常用命令
- 五、自動化測試
- 自動化測試
- python 筆試題
- selenium面試題
- 如何判斷一個頁面上元素是否存在?
- 如何提高腳本的穩定性?
- 如何定位動態元素?
- 如何通過子元素定位父元素?
- 如果截取某一個元素的圖片,不要截取全部圖片
- 平常遇到過哪些問題?如何解決的
- 一個元素明明定位到了,點擊無效(也沒報錯),如果解決?
- selenium中隱藏元素如何定位?(hidden、display: none)
- 六、接口測試
- 接口測試常規面試題
- 接口自動化面試題
- json和字典dict的區別?
- 測試的數據你放在哪?
- 什么是數據驅動,如何參數化?
- 下個接口請求參數依賴上個接口的返回數據
- 依賴于登錄的接口如何處理?
- 依賴第三方的接口如何處理
- 不可逆的操作,如何處理,比如刪除一個訂單這種接口如何測試
- 接口產生的垃圾數據如何清理
- 一個訂單的幾種狀態如何全部測到,如:未處理,處理中,處理失敗,處理成功
- python如何連接數據庫操作?
- 七、App測試
- 什么是activity?
- Activity生命周期?
- Android四大組件
- app測試和web測試有什么區別?
- android和ios測試區別?
- app出現ANR,是什么原因導致的?
- App出現crash原因有哪些?
- app對于不穩定偶然出現anr和crash時候你是怎么處理的?
- app的日志如何抓取?
- logcat查看日志步驟
- 你平常會看日志嗎, 一般會出現哪些異常
- 抓包工具
- fiddler
- Wireshark
- 安全/滲透測試
- 安全性測試都包含哪些內容?
- 開放性思維題
- 面試題
- 字節測試面試
- 一、計算機網絡
- 二、操作系統
- 三、數據庫
- 四、數據結構與算法
- 五、Python
- 六、Linux
- 七、測試用例
- 八、智力/場景題
- 九、開放性問題
- python3_收集100+練習題(面試題)
- python3_100道題目答案
- 接口測試
- 接口測試實例_01
- python+requests接口自動化測試框架實例詳解
- 性能測試
- 性能測試流程
- 性能測試面試題
- 如何編寫性能測試場景用例
- 性能測試:TPS和QPS的區別
- jmeter
- jmeter安裝配置教程
- Jmeter性能測試 入門
- PyCharm
- 快捷工具
- 1-MeterSphere
- 一、安裝和升級
- 2- MobaXterm 教程
- 3-fiddler抓包
- 4-Xshell
- Xshell的安裝和使用
- Xshell遠程連接失敗怎么解決
- 5-Vmware
- Vmware提示以獨占方式鎖定此配置文件失敗
- Windows10徹底卸載VMWare虛擬機步驟
- VM ware無法關機,虛擬機繁忙
- VMware虛擬機下載與安裝
- 解決VM 與 Device/Credential Guard 不兼容。在禁用 Device/Credential Guard 后,可以運行 VM 的方法
- VMware虛擬機鏡像克隆與導入
- 6-WPS
- 1.WPS文檔里的批注怎么刪除
- 2.wps表格中設置圖表的坐標
- 3. wps快速繪制數學交集圖
- 7-MongoDB
- Win10安裝配置MongoDB
- Navicat 15.x for MongoDB安裝破解教程
- Apache
- apache層的賬戶權限控制,以及apache黑名單白名單過濾功能
- HTTP / HTTPS協議
- HTTP協議詳解
- 代理
- 狀態碼詳解
- HTTPS詳解
- Selenium3+python3
- (A) selenium
- selenium自動化環境搭建(Windows10)
- 火狐firebug和firepath插件安裝方法(最新)
- 元素定位工具和方法
- Selenium3+python3自動化
- 新手學習selenium路線圖---學前篇
- 1-操作瀏覽器基本方法
- 2-八種元素定位方法
- 3-CSS定位語法
- 4-登錄案例
- 5-定位一組元素find_elements
- 6-操作元素(鍵盤和鼠標事件)
- 7-多窗口、句柄(handle)
- 8-iframe
- 9-select下拉框
- 10-alert\confirm\prompt
- 11-JS處理滾動條
- 12-單選框和復選框(radiobox、checkbox)
- 13-js處理日歷控件(修改readonly屬性)
- 14-js處理內嵌div滾動條
- 15-table定位
- 16-js處理多窗口
- 17-文件上傳(send_keys)
- 18-獲取百度輸入聯想詞
- 19-處理瀏覽器彈窗
- 20-獲取元素屬性
- 21-判斷元素存在
- 22-爬頁面源碼(page_source)
- 23-顯式等待(WebDriverWait)
- 24-關于面試的題
- 25-cookie相關操作
- 26-判斷元素(expected_conditions)
- 27-判斷title(title_is)
- 28-元素定位參數化(find_element)
- 29-18種定位方法(find_elements)
- 30- js解決click失效問題
- 31- 判斷彈出框存在(alert_is_present)
- 32- 登錄方法(參數化)
- 33- 判斷文本(text_to_be_present_in_element)
- 34- unittest簡介
- 35- unittest執行順序
- 36- unittest之裝飾器(@classmethod)
- 37- unittest之斷言(assert)
- 38- 捕獲異常(NoSuchElementException)
- 39- 讀取Excel數據(xlrd)
- 40- 數據驅動(ddt)
- 41- 異常后截圖(screenshot)
- 42- jenkins持續集成環境搭建
- 43- Pycharm上python和unittest兩種運行方式
- 44- 定位的坑:class屬性有空格
- 45- 只截某個元素的圖
- 46- unittest多線程執行用例
- 47- unittest多線程生成報告(BeautifulReport)
- 48- 多線程啟動多個不同瀏覽器
- (B) python3+selenium3實現web UI功能自動化測試框架
- (C) selenium3常見報錯處理
- 書籍
- (D)Selenium3自動化測試實戰--基于Python語
- 第4章 WebDriver API
- 4.1 從定位元素開始
- 4.2 控制瀏覽器
- 4.3 WebDriver 中的常用方法
- 4.4 鼠標操作
- 4.5 鍵盤操作
- 4.6 獲得驗證信息
- 4.7 設置元素等待
- 4.8 定位一組元素
- 4.9 多表單切換
- 4.10 多窗口切換
- 4.11 警告框處理
- 4.12 下拉框處理
- 4.13 上傳文件
- 4.14 下載文件
- 4.15 操作cookie
- 4.16 調用JavaScript
- 4.17 處理HTML5視頻播放
- 4.18 滑動解鎖
- 4.19 窗口截圖
- 第5章 自動化測試模型
- 5.3 模塊化與參數化
- 5.4 讀取數據文件
- 第6章 unittest單元測試框架
- 6.1 認識unittest