如何为Dash DataTable新增列设置预定义默认值?
解决Dash DataTable添加新列时自动填充所有行默认值的问题
当前代码添加新列时仅更新了表格的columns属性,未同步更新data,导致新列的所有行没有默认值。要实现需求,需同时更新columns和data,为每一行添加新列的默认值(此处为0)。
修改后的完整代码
import pathlib as pl import dash from dash import dash_table from dash.dash_table.Format import Format, Scheme, Sign, Symbol from dash import dcc from dash import html import plotly.graph_objs as go import pandas as pd from dash.dependencies import Input, Output, State table_header_style = { "backgroundColor": "rgb(2,21,70)", "color": "white", "textAlign": "center", } app = dash.Dash(__name__) app.title = "Trial" server = app.server APP_PATH = str(pl.Path(__file__).parent.resolve()) list_rows = ['a', 'b', 'c', 'd'] tasks = ['task' + str(i) for i in range(5)] data = {task:[0 for i in range(len(list_rows))] for task in tasks} app.layout = html.Div( className="", children=[ html.Div( children=[ html.Div( style={}, children=[ html.Div( children=[ html.P(["Study Design"]), html.Div( [ html.Label( [ dcc.Input( id="new-row", placeholder="Row to be added...", type="text", debounce=True, maxLength=20, style={ 'width':'66%', 'margin-left': '5px' } ), html.Button( 'Add', id='add-row-button', n_clicks=0, style={ 'font-size': '10px', 'width': '140px', 'display': 'inline-block', 'margin-bottom': '5px', 'margin-right': '5px', 'margin-left': '5px', 'height':'38px', 'verticalAlign': 'top' } ), ] ), html.Label( [ dcc.Input( id="new-task", placeholder="Task to be added...", type="text", debounce=True, maxLength=50, style={'width':'66%'} ), html.Button( 'Add', id='add-task-button', n_clicks=0, style={ 'font-size': '10px', 'width': '140px', 'display': 'inline-block', 'margin-bottom': '5px', 'margin-right': '5px', 'margin-left': '5px', 'height':'38px', 'verticalAlign': 'top' } ), ] ), ] ), ], ), html.Div( children=[ dash_table.DataTable( id='table', columns=( [{ 'id': 'name', 'name': 'Name', 'type': 'text', 'deletable': True, 'renamable': True, }] + [{ 'id': task, 'name': task, 'type': 'numeric', 'deletable': True, 'renamable': True, 'format': Format( precision=0, scheme=Scheme.fixed, symbol=Symbol.yes, symbol_suffix='h' ), } for task in tasks] ), data=[dict(name=i, **{task: 0 for task in tasks}) for i in list_rows], editable=True, style_header=table_header_style, active_cell={"row": 0, "column": 0}, selected_cells=[{"row": 0, "column": 0}], ), ], ), ], ), ], ), ], ) # 修改后的添加列回调:同时更新columns和data @app.callback( [Output('table', 'columns'), Output('table', 'data')], Input('add-task-button', 'n_clicks'), State('new-task', 'value'), State('table', 'columns'), State('table', 'data')) def update_columns_and_data(n_clicks, new_task, existing_columns, existing_data): if n_clicks > 0 and new_task: # 添加与初始列格式一致的新列定义 existing_columns.append({ 'id': new_task, 'name': new_task, 'type': 'numeric', 'deletable': True, 'renamable': True, 'format': Format( precision=0, scheme=Scheme.fixed, symbol=Symbol.yes, symbol_suffix='h' ), }) # 为每一行添加新列的默认值0 for row in existing_data: row[new_task] = 0 return existing_columns, existing_data # Callback to add row @app.callback( Output(component_id='table', component_property='data'), Input(component_id='add-row-button', component_property='n_clicks'), State(component_id='new-row', component_property='value'), State(component_id='table', component_property='columns'), State(component_id='table', component_property='data')) def update_rows(n_clicks, new_row, columns, rows): if n_clicks > 0 and new_row: rows.append( { 'name': new_row, **{column['id']: 0 for column in columns[1:]} } ) return rows if __name__ == "__main__": app.run_server(debug=True)
关键修改说明
- 回调输出扩展:将添加列的回调输出从仅
columns改为[columns, data],实现列结构与数据的同步更新 - 新列格式统一:补充新列的
type和format配置,确保与初始任务列的数字+小时格式一致 - 数据填充逻辑:遍历现有所有行,为每行新增新列的键值对,值设为默认的0
- 空值校验:添加
new_task非空判断,避免用户输入空值时创建无效列
内容的提问来源于stack exchange,提问作者The Governor
相关产品推荐
相关产品推荐

