我試圖在 StructBlock 上運行一些單元測驗,它由普通塊欄位和 StreamBlock 組成。
我遇到的問題是我可以構建一個渲染塊的測驗,但我無法測驗 StreamBlock 驗證(即,我無法測驗塊的clean())
堆
- 蟒蛇 3.9.6
- 姜戈 3.2
- 鹡鸰 2.13
- pytest 6.2
- pytest-django 4.4
塊定義
我的結構塊
class MyStructBlock(blocks.StructBlock):
image = ImageChooserBlock()
heading = blocks.CharBlock(required=True)
description = blocks.RichTextBlock(features=["bold", "italic"])
links = blocks.StreamBlock([("link", LinkBlock())], icon="link", min_num=1, max_num=6)
class Meta:
icon = "list-ul"
template = "blocks/two_column_with_link_list_block.html"
鏈接塊
class LinkBlock(blocks.StructBlock):
link_text = blocks.CharBlock()
internal_link = blocks.PageChooserBlock()
internal_document = DocumentChooserBlock()
external_link = blocks.URLBlock()
通過這個設定,我創建了這種block_definition:
{
'image': <Image: Thumbnail of subject>,
'heading': 'SomeText',
'description': 'Hello, Son',
'links':
[
{'value':
{
'link_text': 'Walk trip thought region.',
'internal_link': None,
'document_link': None,
'external_link': 'www.example.com'
}
},
{'value': {...}},
{'value': {...}},
]
}
然后像這樣的測驗將作業得很好:
def test_structure():
my_struct_block = MyStructBlock()
block_def = block_definition
rendered_block_html = BeautifulSoup(my_struct_block.render(value=block_def)))
assert <<THINGS ABOUT THE STRUCTURE>>
塊呈現,一切都很好,但是當我嘗試clean塊時,一切都開始橫向發展。
def test_validation():
my_struct_block = MyStructBlock()
block_def = block_definition
rendered_block_html = BeautifulSoup(my_struct_block.render(my_struct_block.clean(block_def)))
將導致這樣的事情:
self = <wagtail.core.blocks.field_block.RichTextBlock object at 0x7f874f430580>, value = 'Hello, Son'
def value_for_form(self, value):
# Rich text editors take the source-HTML string as input (and takes care
# of expanding it for the purposes of the editor)
> return value.source
E AttributeError: 'str' object has no attribute 'source'
.direnv/python-3.9.6/lib/python3.9/site-packages/wagtail/core/blocks/field_block.py:602: AttributeError
哪個描述性足夠——我知道它需要一個 Richtext Block 定義——但為什么會有不同呢?
注意:我嘗試將block_definitionusing定義RichText為期望 RichText 的欄位的值,但失敗了。如果我洗掉該RichText欄位,清理會在dicts我用來定義LinkBlock.
問題
有沒有一種規范的方法來設定這樣一個可以處理復雜塊的測驗,以便塊定義的公共源可以測驗render以及clean和render?或者,在某種程度上,這種型別的塊是否需要一種集成方法,在該方法中我構造一個添加了復雜塊stream_data的頁面,然后請求該頁面并使用回應的呈現?
uj5u.com熱心網友回復:
每個塊型別都有一個對應的“本機”資料型別,用于它希望使用的資料 - 對于更簡單的塊,這種資料型別是您所期望的(例如 CharBlock 的字串,ImageChooserBlock 的 Image 實體)但對于一些更復雜的,定義了一個自定義型別:
- 對于 RichTextBlock,本機型別是
wagtail.core.rich_text.RichText(其行為類似于字串,但還有一個source屬性,例如頁面鏈接中的頁面 ID 保持不變) - 對于 StreamBlock,本機型別是
wagtail.core.blocks.StreamValue(序列型別,其中每個專案都是一個帶有block_type和value屬性的 StreamValue )。
render如果您使用錯誤的型別(例如 RichTextBlock 的字串或 StreamBlock 的字典串列),該方法通常會非常寬容,因為它實際上只是呼叫您自己的模板代碼。該clean方法將更加挑剔,因為它運行特定于每個塊的 Python 邏輯。
不幸的是,用于每個塊的正確型別并沒有真正正式記錄下來,并且其中一些構建起來非常繁瑣(例如,需要向 StructValue 傳遞對相應 StructBlock 的參考)——在測驗代碼之外,沒有非常需要從頭開始創建這些物件,因為資料通常來自某些外部源(例如表單提交或資料庫),并且每個塊都將負責將其轉換為它的本機型別。
考慮到這一點,我建議您通過搭載該to_python方法來構建資料,該方法將存盤在資料庫中的 JSON 表示(僅由簡單的 Python 資料型別 - 整數、字串、串列、字典組成)轉換為本機資料型別:
block_def = my_struct_block.to_python({
'image': 123, # the image ID
'heading': 'SomeText',
'description': 'Hello, Son',
'links':
[
{'type': 'link', 'value':
{
'link_text': 'Walk trip thought region.',
'internal_link': None,
'document_link': None,
'external_link': 'www.example.com'
}
},
{'type': 'link', 'value': {...}},
{'type': 'link', 'value': {...}},
]
})
my_struct_block.clean(block_def) 希望然后成功。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/398973.html
