使用Django 項目中的 ORM 編寫偽造測試數據腳本

2021-01-10 HelloGitHub

作者:HelloGitHub-追夢人物

為了防止博客首頁展示的文章過多以及提升加載速度,可以對文章列表進行分頁展示。不過這需要比較多的文章才能達到分頁效果,但本地開發時一般都只有幾篇測試文章,如果一篇篇手工添加將會非常麻煩。

解決方案是我們可以寫一個腳本,自動生成任意數量的測試數據。腳本寫好後,只需運行腳本就可以往資料庫填充大量測試數據。腳本就是一段普通的 Python 代碼,非常簡單,但是通過這個腳本你將學會如何在 django 外使用 ORM,而不僅僅在 django 應用的內部模塊使用。

腳本目錄結構

一般習慣於將項目有關的腳本統一放在項目根目錄的 scripts 包中,當然這只是一個慣例,你也可以採用自己覺得合理的目錄結構,只要保證這個包所在目錄能夠被 Python 找到。

依據慣例,我們博客項目中腳本的目錄結構如下:

HelloDjango-blog-tutorial\ blog\ blogproject\ ... scripts\ __init__.py fake.py md.sample其中 fake.py 是生成測試數據的腳本,md.sample 是一個純文本文件,內容是用於測試 Markdown 的文本。

使用 Faker 快速生成測試數據

博客文章包含豐富的內容元素,例如標題、正文、分類、標籤。如果手工輸入這些相關元素的文本會非常耗時,我們將藉助一個 Python 的第三方庫 Faker[3]來快速生成這些測試用的文本內容。Faker 意為造假工廠,顧名即可思義。

首先安裝 Faker:

$ pipenv install FakerFaker 通過不同的 Provider 來提供各種不同類型的假數據,我們將在下面的腳本中講解它的部分用法,完整的用法可以參考其官方文檔[4]。

批量生成測試數據

現在我們來編寫一段 Python 腳本用於自動生成博客測試數據。思路非常簡單,博客內容包括作者、分類、標籤、文章等元素,只需依次生成這些元素的內容即可。當然為了使腳本能夠正常運行,很多細節需要注意,我們會對需要注意的地方進行詳細講解。

先來看腳本 fake.py 開頭的內容:

import osimport pathlibimport randomimport sysfrom datetime import timedeltaimport djangoimport fakerfrom django.utils import timezone# 將項目根目錄添加到 Python 的模塊搜索路徑中back = os.path.dirnameBASE_DIR = back(back(os.path.abspath(__file__)))sys.path.append(BASE_DIR)這一段很簡單,只是導入一些會用到的模塊,然後通過腳本所在文件找到項目根目錄,將根目錄添加到 Python 的模塊搜索路徑中,這樣在運行腳本時 Python 才能夠找到相應的模塊並執行。

接下來是腳本的邏輯,先看第一段:

if __name__ == '__main__': os.environ.setdefault("DJANGO_SETTINGS_MODULE", "blogproject.settings.local") django.setup() from blog.models import Category, Post, Tag from comments.models import Comment from django.contrib.auth.models import User這是整個腳本最為重要的部分。首先設置 DJANGO_SETTINGS_MODULE 環境變量,這將指定 django 啟動時使用的配置文件,然後運行 django.setup() 啟動 django。這是關鍵步驟,只有在 django 啟動後,我們才能使用 django 的 ORM 系統。django 啟動後,就可以導入各個模型,以便創建數據。

接下來的邏輯就很簡單了,不斷生成所需的測試數據即可,我們來一段一段地看:

print('clean database') Post.objects.all().delete() Category.objects.all().delete() Tag.objects.all().delete() Comment.objects.all().delete() User.objects.all().delete()這一段腳本用於清除舊數據,因此每次運行腳本,都會清除原有數據,然後重新生成。

print('create a blog user') user = User.objects.create_superuser('admin', 'admin@hellogithub.com', 'admin') category_list = ['Python學習筆記', '開源項目', '工具資源', '程式設計師生活感悟', 'test category'] tag_list = ['django', 'Python', 'Pipenv', 'Docker', 'Nginx', 'Elasticsearch', 'Gunicorn', 'Supervisor', 'test tag'] a_year_ago = timezone.now() - timedelta(days=365) print('create categories and tags') for cate in category_list: Category.objects.create(name=cate) for tag in tag_list: Tag.objects.create(name=tag) print('create a markdown sample post') Post.objects.create( title='Markdown 與代碼高亮測試', body=pathlib.Path(BASE_DIR).joinpath('scripts', 'md.sample').read_text(encoding='utf-8'), category=Category.objects.create(name='Markdown測試'), author=user, )這個腳本沒什麼說的,簡單地使用 django 的 ORM API 生成博客用戶、分類、標籤以及一篇 Markdown 測試文章。

print('create some faked posts published within the past year') fake = faker.Faker() # English for _ in range(100): tags = Tag.objects.order_by('?') tag1 = tags.first() tag2 = tags.last() cate = Category.objects.order_by('?').first() created_time = fake.date_time_between(start_date='-1y', end_date="now", tzinfo=timezone.get_current_timezone()) post = Post.objects.create( title=fake.sentence().rstrip('.'), body='\n\n'.join(fake.paragraphs(10)), created_time=created_time, category=cate, author=user, ) post.tags.add(tag1, tag2) post.save()這段腳本用於生成 100 篇英文博客文章。博客文章通常內容比較長,因此我們使用了之前提及的 Faker 庫來自動生成文本內容。腳本邏輯很清晰,只對其中涉及的幾個知識點進行講解:

fake = faker.Faker('zh_CN') for _ in range(100): # Chinese tags = Tag.objects.order_by('?') tag1 = tags.first() tag2 = tags.last() cate = Category.objects.order_by('?').first() created_time = fake.date_time_between(start_date='-1y', end_date="now", tzinfo=timezone.get_current_timezone()) post = Post.objects.create( title=fake.sentence().rstrip('.'), body='\n\n'.join(fake.paragraphs(10)), created_time=created_time, category=cate, author=user, ) post.tags.add(tag1, tag2) post.save()這一段腳本和上一段幾乎完全一樣,唯一不同的是構造 Faker 實例時,傳入了一個語言代碼 zh_CN,這將生成中文的虛擬數據,而不是默認的英文。

print('create some comments') for post in Post.objects.all()[:20]: post_created_time = post.created_time delta_in_days = '-' + str((timezone.now() - post_created_time).days) + 'd' for _ in range(random.randrange(3, 15)): Comment.objects.create( name=fake.name(), email=fake.email(), url=fake.uri(), text=fake.paragraph(), created_time=fake.date_time_between( start_date=delta_in_days, end_date="now", tzinfo=timezone.get_current_timezone()), post=post, ) print('done!')最後依葫蘆畫瓢,給前 20 篇文章(Post) 生成評論數據。要注意的是評論的發布時間必須位於被評論文章的發布時間和當前時間之間,這就是 delta_in_days = '-' + str((timezone.now() - post_created_time).days) + 'd' 這句代碼的作用。

執行腳本

腳本寫好了,在項目根目錄執行下面的命令運行整個腳本:

$ pipenv run python -m scripts.fake看到如下的輸出說明腳本執行成功了。

clean databasecreate a blog usercreate categories and tagscreate a markdown sample postcreate some faked posts published within the past yearcreate some commentsdone!運行開發伺服器,訪問博客首頁可以看到生成的測試數據,是不是有點以假亂真的感覺?

現在,我們有了 200 多篇測試文章,用來測試分頁效果就十分簡單了,接下來讓我們來實現功能完整的分頁效果。

參考資料

[1]HelloGitHub-追夢人物: https://www.zmrenwu.com

[2]HelloGitHub-Team 倉庫: https://github.com/HelloGitHub-Team/HelloDjango-blog-tutorial

[3]Faker: https://github.com/joke2k/faker

[4]官方文檔: http://faker.rtfd.org/

『講解開源項目系列』——讓對開源項目感興趣的人不再畏懼、讓開源項目的發起者不再孤單。跟著我們的文章,你會發現編程的樂趣、使用和發現參與開源項目如此簡單。歡迎留言聯繫我們、加入我們,讓更多人愛上開源、貢獻開源~

相關焦點

  • APIJSON 3.1.0 發布,Star 超第 2 大 ORM 庫 Hibernate
    因為 APIJSON 是自動化的,後端不用寫代碼,就能自動解析前端傳的 JSON 參數,自動轉為 SQL 語句並連接資料庫執行,然後返回對應的 JSON 結果,期間自動校驗權限、數據、結構,自動防 SQL 注入。
  • 按鍵精靈的使用-安裝並製作第一個小腳本
    按鍵精靈的使用,以按鍵精靈2014為例首先從官網或本人從提供的連結下載按鍵精靈,下載後雙擊安裝包,出現的界面如下:然後點擊自定義安裝,可以更改安裝路徑,還可以同時安裝按鍵精靈(安卓版),我們講的PC端的,所以我們把這個鉤去掉,路徑設置好就直接點擊開始安裝,然後等待一小會
  • 使用腳本繪製吸附勢能面
    其實手動撒點,再採集數據也是可行的,但是會比較麻煩,因此作者根據實際需要開發了一款腳本scan_adsorption_energy用於自動完成這個過程。腳本使用Python編寫,需要numpy和matplotlib第三方庫。 我們首先算好一個吸附例子得到CONTCAR,這個可以讓我們得到吸附分子的元素信息和理想的吸附高度。
  • python3腳本篇1-串口通訊腳本
    前言本文我們來學習Python軟體包pyserial的使用,硬體採用wemos D1開發板,直接燒錄串口章節代碼即可,本文主要編寫PC端Python腳本,完成腳本和外接串口設備通訊的功能。主線程中處理邏輯比較簡單,當用戶輸入數據不是「quit」時候,直接發送給串口設備,否則關閉串口,退出主線程。三、運行1.
  • GitHub十大熱門Python項目 | 網際網路數據資訊網-199IT | 中文互聯...
    Python作為一種神奇而又通用的程式語言,已經被成千上萬的開發者用來構建各種有趣而有用的項目。在下面的部分,我們將嘗試涵蓋GitHub上一些使用Python構建的最佳項目。Airflow可以讓你對你的工作流進行一系列的活動,比如編寫、調度和監控它們。當工作流被定義為代碼時,就會變得更容易管理、測試和協作。它提供了可擴展性、動態管道生成和可擴展性。簡單的用戶界面使Airflow的工作變得順暢,其與其他工具和服務的強大集成能力有助於通過節省時間來獲得最大的效益。Airflow正被業內一些大公司積極使用,如Adobe、Lyft、Slack、Expedia等。
  • LoadRunner壓力測試實際運用的使用方法
    錄製完成後, 按下「 結束錄製」 按鈕,VuGen 自動生成用戶腳本, 退出錄製過程。完善測試腳本當錄製完一個基本的用戶腳本後, 在正式使用前我們還需要完善測試腳本, 增強腳本的靈活性。一般情況下, 我們通過以下幾種方法來完善測試腳本。插入事務、插入結合點、插入註解、參數化輸入。這裡只舉例介紹參數化如何設置,其它只作簡單介紹。
  • 推薦14款開源的Web應用測試工具
    1.JMeter是Apache組織的開放原始碼項目,它是功能和性能測試的工具,100%的用java實現。2.GrinderGrinder是一個負載測試框架,通過Jython來編寫測試腳本,基於HTTP的測試可以由瀏覽器來記錄整個要測試的過程。
  • 詳解Python在資料庫測試中的應用
    對於我們的測試工作而言,Python最吸引我們的特性有如下幾個方面:  1 具備語言粘合劑的能力  2 解釋執行的機制  3 語法簡單易學  4 相對較高的性能  語言粘合劑是比較形象的說法,具體的說,Python支持通過引入自帶的cytpes庫,達到在python腳本中執行已有的動態庫中的代碼的目標。
  • 在LabVIEW中使用編程和調試
    隨著測試需求的快速變化和測試項目開發周期的縮短,您和團隊能夠最大程度地復用現有測試軟體和測量庫的能力尤為重要。 那為什麼測試工程師不能更廣泛地復用更多軟體呢? 以下是測試團隊最常給到的答覆: 軟體是調任或離職同事所開發的遺留軟體; 該軟體正在使用中,如果對未知部分進行更改,可能會有很大的風險,而且費用也很高。
  • IT職業新方向」技術大牛獨家繪製的接口測試學習路線圖…
    所以為了很大程度上減少返工,針對系統內部以及外部的接口進行測試,一方面測試工作可以介入的更早一些,另一方面接口測試與界面是無關的。所以鑑於此,接口測試的優勢就越來越被企業所重視。2.隨著系統跨平臺的發展趨勢愈演愈烈,以及不同系統之間數據交換的頻率越來越高,接口的設計和存在也越來越廣泛了。所以在一個系統中存在多種多樣的接口就演變為一種必然的技術架構模式。
  • Python啥都行_Robot自動化測試
    它可用於測試分布式異構應用程式,其中驗證需要涉及多種技術和接口。更本質一點就是可以把你編寫好的函數導出來,然後像寫存儲過程一樣寫代碼,達到降低難度的目的。啟用易於使用的表格語法,以統一的方式創建測試套件、用例提供從現有關鍵字創建可重複使用的更高級別關鍵字的功能提供易於閱讀的結果報告和HTML格式的日誌為Selenium提供Web測試,GUI測試,運行進程,Telnet,SSH等支持支持創建數據驅動的測試用例內置對變量的支持,支持if、for語句特別適用於不同環境下的測試Robot 技術架構該測試數據是簡單,易於編輯表格格式
  • SQL server資料庫存儲過程測試方法
    有兩種基本的方法可以用來編寫針對SQL存儲過程的輕量級的自動化測試。  第一種方法是在原始的SQL環境中編寫自動化測試代碼,也就是說測試套件代碼(harness code)用於T-SQL語言來編寫的,並且在類似於查詢分析器(QueryAnalyzer)或者Management Studio這樣的程序裡被執行。
  • Python 腳本案例:為流域插值雨量計
    用戶可以在腳本編輯器中直接創建、管理和執行腳本,並提供腳本示例來幫助您入門。通過提供對所有GIS、模型和時間序列數據的直接訪問(從PCSWMM7.2版本開始,將支持所有任何格式的數據導入!及導出到任意格式,處理任意的結果分析!)PCSWMM中的Python腳本幾乎可以完成任何事情:從智能化模型開發過程和執行實時洪水預報,到支持從讀取和寫入到第三方文件格式。
  • 安卓螞蟻森林能量腳本V1.3-無需ROOT+支持模擬器
    安卓螞蟻森林能量腳本-無障礙模式,無需Root權限功能收自己+偷列表收別人澆給自己的水幫列表收能量模式定時模式 (手動定時啟動腳本)掛機模式 (循環掛機運行腳本)自動模式 (自動檢測好友能量成熟剩餘時間並定時運行腳本)以上為已完成的功能(自動模式未添加)
  • 軟體測試中的性能測試 負載測試 壓力測試
    當然不知說這些,還要說在項目的哪一塊用過,有沒有遇到什麼問題之類的。2.Jmeter的工作原理是什麼?jmeter是建立一個線程池,多線程運行sampler來產生負載,通過添加監聽器(聚合報告、圖形結果和察看結果樹等)來記錄測試結果 ,還可以通過斷言來驗證結果的正確性。
  • Unity開發技巧:使用腳本修改粒子
    Unity 3D提供了一個巨大的API,它提供了操縱遊戲中絕大多數對象的方法。然而,有些特性並不如您所希望的那樣強大。舉個例子,例如,部分系統類。比方說,你有一個粒子系統。您需要使用腳本修改粒子系統的形狀半徑。
  • 計算應力應變曲線腳本idealdeform.sh使用指南
    本文版權歸ponychen所有,請關注他的GitHub的主頁獲取腳本!在材料力學強度的表徵測試中,理想拉伸曲線是其中典型的一種方式。從拉伸曲線中我們可以獲得彈性模量,屈服強度等等有用的力學係數。使用第一性原理模擬理想拉伸(不局限於拉伸,但要注意,不要將宏觀應力應變與DFT計算的理想應力應變混淆)曲線當然是一種很fancy的方法,但是目前我沒有看到一個自動化實現這個過程的腳本。我用bash寫了一個idealdeform.sh腳本,可以自動化實現理想拉伸或者剪切過程,目前主要用於VASP。Nanoscale, 2017, 9, 850–855還是先講講原理吧。
  • Stellaris開發日誌#182 | 9/3 編寫腳本時的風險及如何避免它們
    我是Caligula,Stellaris的內容設計師之一,這意味著我負責各種基於敘事性寫作和編寫腳本的工作——「編寫腳本Scripting」是我們的術語,要做的事情與編程類似,但不會改變原始碼。換句話說,我做的就是Mod開發者們所做的事情(不過我有一個顯著優勢,那就是我可以查看到原始碼,並在需要的時候改變它們)。