【问题标题】:How do I take all inputs from a dash page and store them in a database/dataframe?如何从破折号页面获取所有输入并将它们存储在数据库/数据框中?
【发布时间】:2023-03-03 01:35:01
【问题描述】:

我有一个破折号脚本,让用户填写输入和下拉列表;首先输入,然后填写下拉数据表。填写完这些输入和数据表后,我需要获取这些输入和数据表,并在单击“提交”按钮后,将其存储为 pandas 数据框或字典或存储在数据库中(坦率地说,以最简单的为准)。

我觉得我当然可能需要使用 dcc.Store 和回调,但我不确定如何继续。 任何帮助表示赞赏,谢谢!

app = dash.Dash(__name__)
app.config['suppress_callback_exceptions'] = True

df = pd.DataFrame(OrderedDict([
    ('Product', ['Benzene', 'HDPE', 'Propylene', 'Benzene']),
    ('Function', ['Input1', 'Input2', 'Input3', 'Input2']),
    ('Conversion Factor', [1, 2, 1, 3]),
    ('Measure Unit', ['Tonne', 'Kilo', 'Tonne', 'Gram']),
]))


app.layout = html.Div(
    children=[
        html.H1(children='Technology Information',
                style={'font-family': 'calibri'}),
        dcc.Store(id='memory'),
        dbc.FormGroup([
            dbc.Label('Technology Name:',
                      html_for='tech-name-row',
                      style={'font-family': 'calibri',
                             'margin-right': '4em'}),
            dbc.Col(dbc.Input(type='technology',
                              id='tech-name-row',
                              placeholder='Enter Technology Name',
                              style={'display': 'inline-flex',
                                     'verticalAlign': 'middle',
                                     'height': '25px'}),
                    style={'display': 'inline-flex',
                           'verticalAlign': 'middle'}),
        ], row=True, style={'margin-bottom': '1em'}),
        html.Label(["Technology Type:", dcc.Dropdown(id="tech-type-drop",
                                                     style={'display': 'inline-block',
                                                            'width': '175px',
                                                            'height': '28px',
                                                            'margin-left': '2.3em',
                                                            'verticalAlign': 'middle',
                                                            'font-size': '15px'},
                                                     placeholder='Select Type',
                                                     options=[
                                                        {"label": "Type 1", "value": "1"},
                                                        {"label": "Type 2", "value": "2"},
                                                        {"label": "Type 3", "value": "3"}])],
                   style={'font-family': 'calibri',
                          'margin-right': '4em',
                          'display': 'flex'}),
        html.H1('                                   '),
        html.H1('                                   '),
        html.H2('Process Information',
                style={'font-family': 'calibri',
                       'margin-right': '0.5em',
                       'margin-top': '3em',
                       'display': 'inline'}),
        html.Button(children='+',
                    id='add_process_button',
                    style={'background-color': '#38BC23',
                           'display': 'inline'}),
        html.Div(id='process_list', children=[]),
        html.Div(id='process_output', children='No output'),
        html.Button(children='Submit',
                    id='submit-form',
                    type='submit',
                    style={'background-color': '#0099ff',
                           'margin': '1em'}),
    ]
)


@app.callback(
    Output('process_list', 'children'),
    [Input('add_process_button', 'n_clicks'),
     Input({'type': 'remove_process_button', 'index': ALL}, 'n_clicks')
     ],
    [State('process_list', 'children')])
def add_step(n_clicks, _, div_list):

    input_id = dash.callback_context.triggered[0]["prop_id"].split(".")[0]

    if "index" in input_id and n_clicks is not None:
        delete_form = json.loads(input_id)["index"]
        div_list = [form for form in div_list if "'index': " + str(delete_form) not in str(form)]
    else:
        div_list += [html.Div(children=[
            dcc.Store(id='memory'),
            html.Button(children='-',
                        id={'type': 'remove_process_button', 'index': n_clicks},
                        style={'background-color': 'red',
                               'display': 'inline',
                               'float': 'right',
                               'margin': '1em'}),
            dbc.Col(
                dbc.FormGroup(
                    [dbc.Label("Process Name",
                               html_for="process-name",
                               style={'font-family': 'calibri',
                                      'margin-right': '2em'}),
                     dbc.Input(id="process-name",
                               placeholder="Enter Process Name")],
                    style={'margin': '1em'})),
            html.Div(children=[
                dash_table.DataTable(id='process-table',
                                     data=[{}],
                                     style_table={'margin': '2em', 'width': '90%', 'display': 'inline-block'},
                                     style_cell={'font-family': 'calibri', 'textAlign': 'left'},
                                     columns=[{'id': 'Product', 'name': 'Product', 'presentation': 'dropdown'},
                                              {'id': 'Function', 'name': 'Function', 'presentation': 'dropdown'},
                                              {'id': 'Conversion Factor', 'name': 'Conversion Factor',
                                               'presentation': 'dropdown'},
                                              {'id': 'Measure Unit', 'name': 'Measure Unit',
                                               'presentation': 'dropdown'}],
                                     row_deletable=True,
                                     editable=True,
                                     dropdown={'Product': {'options': [{'label': i, 'value': i} for i in
                                                                       ['Benzene', 'HDPE', 'Propylene']]},
                                               'Function': {'options': [{'label': i, 'value': i} for i in
                                                                        ['Input1', 'Input2', 'Input3']]},
                                               'Conversion Factor': {'options': [{'label': i, 'value': i} for i in
                                                                                 ['1', '2', '3']]},
                                               'Measure Unit': {'options': [{'label': i, 'value': i} for i in
                                                                            ['Tonne', 'Kilo', 'Gram']]},
                                               }),
                html.Button('Add Row',
                            style={'background-color': '#38BC23', 'display': 'inline', 'margin': '1em'},
                            id='editing-rows-button',
                            n_clicks=0),
                html.Div(id='process-table-container')
            ])
        ], style={'border': '2px black solid',
                  'margin': '1em'}
        )]
    return div_list


@app.callback(
    Output('process-table', 'data'),
    [Input('editing-rows-button', 'n_clicks')],
    [State('process-table', 'data'),
     State('process-table', 'columns')])
def add_row(n_clicks, rows, columns):
    if n_clicks > 0:
        rows.append({c['id']: '' for c in columns})
    return rows

【问题讨论】:

    标签: python html plotly-dash


    【解决方案1】:

    如果所有内容都将由提交按钮触发,那么您可以设置回调以将提交按钮用作Input,并将其他所有内容用作State 到函数。然后该函数可以根据您的需要打包数据并将其发送到您的数据库、文件系统或其他任何地方。

    【讨论】:

    • 这听起来合乎逻辑且正确,但是当我尝试在状态下使用 dbc.Input 时,例如'tech-name-row' 在这种情况下,我收到一个错误:此 ID 分配给布局中的 dash_bootstrap_components.Input 组件,该组件不支持此属性。我还尝试使用模式匹配回调并给出所有必需的点 id={'type': name, 'index': index} 但由于我已经在回调中使用了数据表,因此证明很困难。
    • 它是另一个回调中的一个属性。即使出现此错误,该代码也可以工作,因此我选择忽略它,直到找到更永久的解决方案。但是,您最初的建议确实很有帮助,让我能够做到这一点,所以谢谢您!
    猜你喜欢
    • 2019-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-22
    • 1970-01-01
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    相关资源
    最近更新 更多