Skip to content

Commit

Permalink
Add support for computed_field in Table component. (#321)
Browse files Browse the repository at this point in the history
  • Loading branch information
hasansezertasan committed May 28, 2024
1 parent 97c4f07 commit 7c921b0
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 16 deletions.
19 changes: 12 additions & 7 deletions src/python-fastui/fastui/components/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,21 @@ def _fill_columns(self) -> _te.Self:
raise ValueError('Cannot infer model from empty data, please set `Table(..., model=MyModel)`')

if self.columns is None:
self.columns = [
display.DisplayLookup(field=name, title=field.title)
for name, field in data_model_type.model_fields.items()
]
self.columns = []
for name, field in data_model_type.model_fields.items():
self.columns.append(display.DisplayLookup(field=name, title=field.title))
for name, field in data_model_type.model_computed_fields.items():
self.columns.append(display.DisplayLookup(field=name, title=field.title))

else:
# add pydantic titles to columns that don't have them
for column in (c for c in self.columns if c.title is None):
field = data_model_type.model_fields.get(column.field)
if field and field.title:
column.title = field.title
model_field = data_model_type.model_fields.get(column.field)
computed_field = data_model_type.model_computed_fields.get(column.field)
if model_field and model_field.title:
column.title = model_field.title
elif computed_field and computed_field.title:
column.title = computed_field.title
return self

@classmethod
Expand Down
46 changes: 37 additions & 9 deletions src/python-fastui/tests/test_tables_display.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import pytest
from fastui import components
from fastui.components import display
from pydantic import BaseModel, Field
from pydantic import BaseModel, Field, computed_field


class User(BaseModel):
id: int
name: str = Field(title='Name')

@computed_field(title='Representation')
@property
def representation(self) -> str:
return f'{self.id}: {self.name}'


users = [User(id=1, name='john'), User(id=2, name='jack')]

Expand All @@ -17,21 +22,40 @@ def test_table_no_columns():

# 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': 'john'}, {'id': 2, 'name': 'jack'}],
'columns': [{'field': 'id'}, {'field': 'name', 'title': 'Name'}],
'data': [
{'id': 1, 'name': 'john', 'representation': '1: john'},
{'id': 2, 'name': 'jack', 'representation': '2: jack'},
],
'columns': [
{'field': 'id'},
{'field': 'name', 'title': 'Name'},
{'field': 'representation', 'title': 'Representation'},
],
'type': 'Table',
}


def test_table_columns():
table = components.Table(
data=users, columns=[display.DisplayLookup(field='id', title='ID'), display.DisplayLookup(field='name')]
data=users,
columns=[
display.DisplayLookup(field='id', title='ID'),
display.DisplayLookup(field='name'),
display.DisplayLookup(field='representation'),
],
)

# 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': 'john'}, {'id': 2, 'name': 'jack'}],
'columns': [{'title': 'ID', 'field': 'id'}, {'field': 'name', 'title': 'Name'}],
'data': [
{'id': 1, 'name': 'john', 'representation': '1: john'},
{'id': 2, 'name': 'jack', 'representation': '2: jack'},
],
'columns': [
{'title': 'ID', 'field': 'id'},
{'title': 'Name', 'field': 'name'},
{'title': 'Representation', 'field': 'representation'},
],
'type': 'Table',
}

Expand All @@ -47,7 +71,11 @@ def test_table_empty_data_model():
# insert_assert(table.model_dump(by_alias=True, exclude_none=True))
assert table.model_dump(by_alias=True, exclude_none=True) == {
'data': [],
'columns': [{'field': 'id'}, {'title': 'Name', 'field': 'name'}],
'columns': [
{'field': 'id'},
{'title': 'Name', 'field': 'name'},
{'title': 'Representation', 'field': 'representation'},
],
'type': 'Table',
}

Expand All @@ -57,7 +85,7 @@ def test_display_no_fields():

# insert_assert(d.model_dump(by_alias=True, exclude_none=True))
assert d.model_dump(by_alias=True, exclude_none=True) == {
'data': {'id': 1, 'name': 'john'},
'data': {'id': 1, 'name': 'john', 'representation': '1: john'},
'fields': [{'field': 'id'}, {'title': 'Name', 'field': 'name'}],
'type': 'Details',
}
Expand All @@ -70,7 +98,7 @@ def test_display_fields():

# insert_assert(d.model_dump(by_alias=True, exclude_none=True))
assert d.model_dump(by_alias=True, exclude_none=True) == {
'data': {'id': 1, 'name': 'john'},
'data': {'id': 1, 'name': 'john', 'representation': '1: john'},
'fields': [{'title': 'ID', 'field': 'id'}, {'title': 'Name', 'field': 'name'}],
'type': 'Details',
}

0 comments on commit 7c921b0

Please sign in to comment.