Skip to content

Commit

Permalink
Respect computed_field title in Table and Details
Browse files Browse the repository at this point in the history
  • Loading branch information
hramezani committed May 5, 2024
1 parent 2775c64 commit 0f9c7e9
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 10 deletions.
8 changes: 4 additions & 4 deletions src/python-fastui/fastui/components/display.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 4 additions & 5 deletions src/python-fastui/fastui/components/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,14 @@ def _fill_columns(self) -> _te.Self:
except IndexError:
raise ValueError('Cannot infer model from empty data, please set `Table(..., model=MyModel)`')

fields = {**data_model_type.model_fields, **data_model_type.model_computed_fields}

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 = [display.DisplayLookup(field=name, title=field.title) for name, field in fields.items()]
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)
field = fields.get(column.field)
if field and field.title:
column.title = field.title
return self
Expand Down
40 changes: 39 additions & 1 deletion src/python-fastui/tests/test_tables_display.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
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):
Expand Down Expand Up @@ -74,3 +74,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 0f9c7e9

Please sign in to comment.