Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Respect computed_field title in Table and Details
Browse files Browse the repository at this point in the history
hramezani committed May 30, 2024
1 parent 61d9b0c commit 9698fbb
Showing 2 changed files with 42 additions and 4 deletions.
8 changes: 4 additions & 4 deletions src/python-fastui/fastui/components/display.py
Original file line number Diff line number Diff line change
@@ -79,14 +79,14 @@ class Details(BaseModel, extra='forbid'):

@pydantic.model_validator(mode='after')
def _fill_fields(self) -> _te.Self:
fields = {**self.data.model_fields, **self.data.model_computed_fields}

if self.fields is None:
self.fields = [
DisplayLookup(field=name, title=field.title) for name, field in self.data.model_fields.items()
]
self.fields = [DisplayLookup(field=name, title=field.title) for name, field in fields.items()]
else:
# add pydantic titles to fields that don't have them
for field in (c for c in self.fields if c.title is None):
pydantic_field = self.data.model_fields.get(field.field)
pydantic_field = fields.get(field.field)
if pydantic_field and pydantic_field.title:
field.title = pydantic_field.title
return self
38 changes: 38 additions & 0 deletions src/python-fastui/tests/test_tables_display.py
Original file line number Diff line number Diff line change
@@ -102,3 +102,41 @@ def test_display_fields():
'fields': [{'title': 'ID', 'field': 'id'}, {'title': 'Name', 'field': 'name'}],
'type': 'Details',
}


def test_table_respect_computed_field_title():
class Foo(BaseModel):
id: int

@computed_field(title='Foo Name')
def name(self) -> str:
return f'foo{self.id}'

foos = [Foo(id=1)]
table = components.Table(data=foos)

# insert_assert(table.model_dump(by_alias=True, exclude_none=True))
assert table.model_dump(by_alias=True, exclude_none=True) == {
'data': [{'id': 1, 'name': 'foo1'}],
'columns': [{'field': 'id'}, {'title': 'Foo Name', 'field': 'name'}],
'type': 'Table',
}


def test_details_respect_computed_field_title():
class Foo(BaseModel):
id: int

@computed_field(title='Foo Name')
def name(self) -> str:
return f'foo{self.id}'

foos = Foo(id=1)
details = components.Details(data=foos)

# insert_assert(table.model_dump(by_alias=True, exclude_none=True))
assert details.model_dump(by_alias=True, exclude_none=True) == {
'data': {'id': 1, 'name': 'foo1'},
'fields': [{'field': 'id'}, {'title': 'Foo Name', 'field': 'name'}],
'type': 'Details',
}

0 comments on commit 9698fbb

Please sign in to comment.