Django-dash: обратный вызов генерирует тег div id, не найденный другим обратным вызовом
Я уже некоторое время работаю с plotly dash и особенно с django-dash, и сейчас столкнулся с проблемой, которую не могу решить. Я в замешательстве, потому что я успешно использовал ту же структуру в прошлом. Надеюсь, пара свежих глаз поможет мне понять, что я делаю не так.
Вот что у меня есть: => первый обратный вызов получает данные из сессии django, которые используются для создания выпадающего меню, содержащего некоторые значения, извлеченные из фрейма данных:
@app.expanded_callback(
Output('output_two', 'children'),
[Input('dummy', 'value')]
)
def clean_data(file_path,**kwargs):
file_path = file_path
path = kwargs['request']
path = path.session.get('path')
print("path", path)
ifc_file = ifcopenshell.open(path)
work_plans = ifc_file.by_type("IfcWorKPlan")
work_plans_df = pd.DataFrame({
'id': [schedule.id() for schedule in work_plans],
'StartTime': [schedule.StartTime for schedule in work_plans],
'FinishTime': [schedule.FinishTime for schedule in work_plans],
})
work_plans_df['StartTime'] = pd.to_datetime(work_plans_df['StartTime']).dt.date
work_plans_df['Status'] = "En cours"
work_plan_id = work_plans_df['id'].unique()
return html.Div(children=[html.Div(
className='five columns',
children=[
dcc.Dropdown(
id="dropdown",
options=list({'label': Id, 'value': Id} for Id in
work_plan_id
),
value='',
),
],
),
],
)
Теперь, второй вызов должен использовать представленное значение выпадающего списка и использовать его для вывода чего-то (я не буду описывать детали вычислений)
@app.callback(
Output('dd-output-container', 'children'),
Input('submit-val', 'n_clicks')
,State('dropdown','value')
)
def process_workplans(path, n_clicks,value,*args,**kwargs):
if value is not None:
...#do calcs
return dt.DataTable(...)
и, наконец, вот макет, который я использую:
app.layout = html.Div([
html.Div(id="dummy"),
html.Div(id="bed_file_path", children=[], style={'display': 'none'}),
dcc.Store(id='output_one'),
# wrapper dashboard
html.Div([ # main-area
html.Div([ # row that includes everything on the same "plane"
html.Div([
html.H4("Carnet d'entretien de mon bien"), html.Hr()]),
html.Div([ # col sm-3, the entire length of the menu
html.Div([ # control the frame in the whitch the menu is displayed
html.Br(),
html.Div([
html.Div([ # this make sure the content takes the 12 spaces within the 3 sm column
html.Div(
className='twelve columns',
children=html.P(
"Sélectionner un chantier",
),
),
html.Div(id="output_two"),
], className='col-sm-12',
style={"border-left": "white solid 0.4rem", "border-right": "white solid 0.4rem"}),
html.Br(),
html.Br(),
html.A(html.Button('Afficher les chantiers', id='submit-val', n_clicks=0,
style={'border-radius': '4px', 'border': '1px solid #ff5402',
'background-color': 'white'}),
style={'margin-right': '3px', 'margin-bottom': '20px', 'margin-left': '30px'}),
html.A(html.Button('Refresh', style={'border-radius': '4px', 'border': '1px solid #ff5402',
'background-color': 'white', 'margin-bottom': '20px'}),
href='/eoq_modeling'),
html.Br(),
], className='col-sm-12',
style={"border-left": "white solid 0.4rem", "border-right": "white solid 0.4rem"}),
html.Br(),
], className='row-for-params')
], className="col-sm-3"),
html.Div([
html.Div(id='dd-output-container'),
], className="col-sm-9")
], className='row')
], className="main-area"),
], className="wrapper-dashboard")
Ошибка, которую я получаю, говорит о том, что dropdown
не может быть найден.
Я вижу, что когда страница инициализируется, dropdown
там нет, но он туда попадает, и второй обратный вызов не может обновить
Я считаю, что задержка срабатывания обратного вызова 2 может быть вариантом, но я не могу найти, как это сделать в документации django-dash, а dash app.config[‘suppress_callback_exceptions’] = True
не работает с django-dash. У кого-нибудь есть идея, как решить эту проблему?
Мне кажется, что:
- Вы можете создать фиктивный div & dropdown (т.е. ту же структуру, которую выведет
clean_data()
) в вашем начальномapp.layout
, а затем просто перезаписать его новыми элементами управления с помощью вашего обратного вызова. Т.е. таким образом у вас всегда будет элемент управления с правильным ID в макете, чтобы избежать инициализации на неполном макете. - Потенциально подавление начального вызова второго обратного вызова может избежать этой проблемы?