Ensure that TypedTableBlock uses the correct API representations of child blocks

TypedTableBlock did not provide a `get_api_representation` method, so it fell back on returning the database JSON representation as returned by `get_prep_value`. This resulted in an API representation that was mostly usable, but failed to respect child blocks that override `get_api_representation` themselves.
pull/12317/head
Matt Westcott 2024-01-25 00:11:04 +00:00 zatwierdzone przez LB (Ben Johnston)
rodzic 5cc22f3f75
commit efa2a88642
4 zmienionych plików z 51 dodań i 1 usunięć

Wyświetl plik

@ -36,6 +36,7 @@ Changelog
* Fix: Ensure that dropdown button toggles show with a border in high contrast mode (Ishwari8104, LB (Ben) Johnston)
* Fix: Update email notification header to the new logo design (rahulsamant37)
* Fix: Change `file_size` field on document model to avoid artificial 2Gb limit (Gabriel Getzie)
* Fix: Ensure that `TypedTableBlock` uses the correct API representations of child blocks (Matt Westcott)
* Docs: Upgrade Sphinx to 7.3 (Matt Westcott)
* Docs: Document how to customize date/time format settings (Vince Salvino)
* Docs: Create a new documentation section for deployment and move fly.io deployment from the tutorial to this section (Vince Salvino)

Wyświetl plik

@ -57,6 +57,7 @@ This release adds formal support for Django 5.1.
* Ensure that dropdown button toggles show with a border in high contrast mode (Ishwari8104, LB (Ben) Johnston)
* Update email notification header to the new logo design (rahulsamant37)
* Change `file_size` field on document model to avoid artificial 2Gb limit (Gabriel Getzie)
* Ensure that `TypedTableBlock` uses the correct API representations of child blocks (Matt Westcott)
### Documentation

Wyświetl plik

@ -163,6 +163,31 @@ class BaseTypedTableBlock(Block):
"caption": "",
}
def get_api_representation(self, table, context=None):
if table:
return {
"columns": [
{"type": col["block"].name, "heading": col["heading"]}
for col in table.columns
],
"rows": [
{
"values": [
column["block"].get_api_representation(val, context=context)
for column, val in zip(table.columns, row["values"])
]
}
for row in table.row_data
],
"caption": table.caption,
}
else:
return {
"columns": [],
"rows": [],
"caption": "",
}
def to_python(self, value):
if value:
columns = [

Wyświetl plik

@ -14,11 +14,14 @@ from wagtail.contrib.typed_table_block.blocks import (
class CountryChoiceBlock(blocks.ChoiceBlock):
"""A ChoiceBlock with a custom rendering, to check that block rendering is honoured"""
"""A ChoiceBlock with a custom rendering and API representation, to check that block rendering is honoured"""
def render_basic(self, value, context=None):
return value.upper() if value else value
def get_api_representation(self, value, context=None):
return f".{value}" if value else value
class TestTableBlock(TestCase):
def setUp(self):
@ -76,6 +79,18 @@ class TestTableBlock(TestCase):
"caption": "Countries and their food",
}
self.api_data = {
"columns": [
{"type": "country", "heading": "Country"},
{"type": "text", "heading": "Description"},
],
"rows": [
{"values": [".nl", "A small country with stroopwafels"]},
{"values": [".fr", "A large country with baguettes"]},
],
"caption": "Countries and their food",
}
def test_value_from_datadict(self):
"""
Test that we can turn posted form data into a TypedTable instance,
@ -174,6 +189,14 @@ class TestTableBlock(TestCase):
table_data = self.block.get_prep_value(table)
self.assertEqual(table_data, self.db_data)
def test_get_api_representation(self):
"""
Test that the API representation honours custom representations of child blocks
"""
table = self.block.to_python(self.db_data)
table_api_representation = self.block.get_api_representation(table)
self.assertEqual(table_api_representation, self.api_data)
def test_clean(self):
table = self.block.value_from_datadict(self.form_data, {}, "table")
# cleaning a valid table should return a TypedTable instance