文章目錄
- 0.思路引導
- 1.腳本目錄結構
- 2.使用 Faker 快速生成測試數據
- 3.批量生成測試數據
- 4.執行腳本
- 5.效果展示
0.思路引導
1)為了防止博客首頁展示的文章過多以及提升加載速度,可以對文章列表進行分頁展示。
2)不過這需要比較多的文章才能達到分頁效果,但本地開發時一般都只有幾篇測試文章,如果一篇篇手工添加將會非常麻煩。
3)解決方案是我們可以寫一個腳本,自動生成任意數量的測試數據。腳本寫好后,只需運行腳本就可以往數據庫填充大量測試數據。
1.腳本目錄結構
在項目根目錄下新建scripts 文件夾,并新建__init__.py,fake.py,md.sample三個文件,目錄結構如下:
HelloDjango-blog-tutorial\blog\blogproject\...scripts\__init__.pyfake.pymd.sample
注意:
1)其中 fake.py 是生成測試數據的腳本;
2)md.sample 是一個純文本文件,內容是生成用于測試 Markdown 的文本。
2.使用 Faker 快速生成測試數據
博客文章包含豐富的內容元素,例如標題、正文、分類、標簽。如果手工輸入這些相關元素的文本會非常耗時,我們將借助一個 Python 的第三方庫 Faker (造假工廠)來快速生成這些測試用的文本內容。
首先安裝 Faker:
$ pipenv install Faker
Faker 通過不同的 Provider 來提供各種不同類型的假數據,我們將在下面的腳本中講解它的部分用法,完整的用法可以參考其官方文檔。
3.批量生成測試數據
文件位置:HelloDjango-blog-tutorial \scropts \fake.py
1)首先,導入一些會用到的模塊,然后通過腳本所在文件找到項目根目錄,將根目錄添加到 Python 的模塊搜索路徑中,這樣在運行腳本時 Python 才能夠找到相應的模塊并執行;
import os
import pathlib
import random
import sys
from datetime import timedeltaimport django
import faker
from django.utils import timezone# 將項目根目錄添加到 Python 的模塊搜索路徑中
back = os.path.dirname
BASE_DIR = back(back(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
2)設置 DJANGO_SETTINGS_MODULE 環境變量,這將指定 django 啟動時使用的配置文件,然后運行 django.setup() 啟動 django。這是關鍵步驟,只有在 django 啟動后,我們才能使用 django 的 ORM 系統。django 啟動后,就可以導入各個模型,以便創建數據。
if __name__ == '__main__':os.environ.setdefault("DJANGO_SETTINGS_MODULE", "blogproject.settings.local")django.setup()from blog.models import Category, Post, Tagfrom comments.models import Commentfrom django.contrib.auth.models import User
3)清除舊數據,因此每次運行腳本,都會清除原有數據,然后重新生成。
print('clean database')Post.objects.all().delete()Category.objects.all().delete()Tag.objects.all().delete()Comment.objects.all().delete()User.objects.all().delete()
4)使用 django 的 ORM API 生成博客用戶、分類、標簽以及一篇 Markdown 測試文章。
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,)
5)生成 100 篇英文博客文章。博客文章通常內容比較長,因此我們使用了之前提及的 Faker 庫來自動生成文本內容
print('create some faked posts published within the past year')fake = faker.Faker() # Englishfor _ 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()
注意:
-
fake = faker.Faker(),要使用 Faker 自動生成數據,首先實例化一個 Faker 對象,然后我們可以在腳本中使用這個實例的一些方法生成需要的數據。Faker默認生成英文數據,但也支持國際化。至于如何生成中文數據在下一段腳本中會看到。
-
order_by(’?’) 將返回隨機排序的結果,腳本中這塊代碼的作用是達到隨機選擇標簽(Tag) 和分類(Category) 的效果。
-
然后就是 2 個 Faker 的 API 了:
fake.date_time_between 這個方法將返回 2個指定日期間的隨機日期。三個參數分別是起始日期,終止日期和時區。我們在這里設置起始日期為 1年前(-1y),終止日期為當下(now),時區為 get_current_timezone 返回的時區,這個函數是django.utils.timezone 模塊的輔助函數,它會根據 django 設置文件中 TIME_ZONE的值返回對應的時區對象。 -
‘\n\n’.join(fake.paragraphs(10)) fake.paragraphs(10) 用于生成 10 個段落文本,以列表形式返回,列表的每個元素即為一個段落。要注意使用 2 個換行符連起來是為了符合 Markdown 語法,Markdown中只有 2 個換行符分隔的文本才會被解析為段落。
6)構造 Faker 實例,傳入了一個語言代碼 zh_CN,這將生成中文的虛擬數據,而不是默認的英文。
fake = faker.Faker('zh_CN')for _ in range(100): # Chinesetags = 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()
7)給前 20 篇文章(Post) 生成評論數據。要注意的是評論的發布時間必須位于被評論文章的發布時間和當前時間之間,這就是 delta_in_days = ‘-’ + str((timezone.now() - post_created_time).days) + ‘d’ 這句代碼的作用。
print('create some comments')for post in Post.objects.all()[:20]:post_created_time = post.created_timedelta_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!')
4.執行腳本
在項目根目錄執行下面的命令運行整個腳本:
$ pipenv run python -m scripts.fake
看到如下的輸出說明腳本執行成功了。
clean database
create a blog user
create categories and tags
create a markdown sample post
create some faked posts published within the past year
create some comments
done!
5.效果展示
此時,我們有了 200 多篇測試文章,用來測試分頁效果就十分簡單了,接下來我們將實現功能完整的分頁效果。