django-plotly-dash
django-plotly-dash copied to clipboard
Problem accessing initial arguments from Dash app
I have followed all the documentation and other answers, but still can't get this to work. I am trying to pass a variable from a Django view, into a template, and then into a Dash app to display. My view is as below:
def model(request, pk): context = {'target_id': {'value': pk}} return render(request, 'model_results.html', {'context':context})
This passes the context into my template, which is below:
{%plotly_app name="tutorial_1" initial_arguments=context %}
My Dash app, as I understand it, should now be able to have the div with id "target_id" have the value passed to it, and is accessible in the extended call back. My app is below:
`app = DjangoDash('tutorial_1')
app.layout = html.Div([ dcc.Input(id='target_id', type = 'hidden'), html.Div(id="output-one") ])
@app.expanded_callback( dash.dependencies.Output('output-one','children'), [dash.dependencies.Input('target_id','value')] ) def callback_c(value, *args,**kwargs): print(value) return value
if name == 'main': app.run_server(debug=True)`
But nothing is returned. If i add an actual value to the id 'target_id', the callback function correctly passes the argument to the output and is displayed. So it seems that for some reason the context is not being passed into my application. Please help!
Change context in your python code to be a string (json.dumps should suffice as it is just a dictionary or use context = "{'target_id': {'value': %s}}" % pk) and use initial_arguments="{{context}}" in your template.
Thank you very much for your reply. When I change to:
` context = "{'target_id': {'value': %s}}" % pk
return render(request, 'model_results.html', {'context':context})`
in my view and in my template:
{%plotly_app name="tutorial_1" initial_arguments="{{context}}" %},
I just get a new error, JSONDecodeError at /model/68/
Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
My mistake. Swap the quotes around to get valid json: context = '{"target_id": {"value": %s}}' % pk
Appreciate it; unfortunately it gives the same error. I tried several different iterations of this, including:
context = ast.literal_eval(context)
return render(request, 'model_results.html', {"context":json.dumps(context)})```
but get the same error, Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
update: i tried to make it even more simple, with this:
return render(request, 'model_results.html', {"context":{"target_id": 67}})
which still gives me the same error. are you sure in the template tag i need the double quotes like this?:
{%plotly_app name="tutorial_1" initial_arguments="{{context}}" %}
all the other examples I see online simply have initial_arguments = context. But then I'm right back where I started, where nothing is displayed in my app
What happens when you use
return render(request, 'model_results.html', {"context":'{"target_id": {"value": 67}}'})
And then in your template
{%plotly_app name="tutorial_1" initial_arguments=context %}
In other words, directly specify the initial arguments as a string and use the variable directly.
If that works (and it should) then you should be able to drop the single quotes in the render call (ie switch the context variable from a string to a dict) and then from there get to constructing it in your code.
No error, but nothing is displayed in the Dash app. At this point, if I could just get the simple '67' to appear on the screen of the Dash app that would be enough to get me going. Is there something wrong with my app code? I don't get an error but it just displays a blank screen.
app = DjangoDash('tutorial_1')
app.layout = html.Div([
dcc.Input(id='target_id', type = 'hidden'),
html.Div(id="output-one")
])
@app.expanded_callback(
dash.dependencies.Output('output-one','children'),
[dash.dependencies.Input('target_id','value')]
)
def callback_c(value, *args,**kwargs):
print(value)
return value
if __name__ == '__main__':
app.run_server(debug=True)```
Are you running this through Django? The last two lines would suggest not.
yes i am; i can get the app to run by changing some of the input information. for example, this app runs perfectly within my Django application:
app.layout = html.Div([
dcc.RadioItems(id="dropdown-one",options=[{'label':i,'value':j} for i,j in [
("O2","Oxygen"),("N2","Nitrogen"),("CO2","Carbon Dioxide")]
],value="Oxygen"),
html.Div(id="target"),
html.Div(id="output-one")
])
@app.callback(
dash.dependencies.Output('output-one','children'),
[dash.dependencies.Input('dropdown-one','value')]
)
def callback_c(*args,**kwargs):
da = kwargs['dash_app']
return "Args are [%s] and kwargs are %s" %(",".join(args), kwargs)
if __name__ == '__main__':
app.run_server(debug=True)```
Is there anything in your app to trigger the callback? I suspect that nothing is causing the callback to be triggered and as a result the app is displaying nothing.
I'd (a) add an extra input component and pass that to the callback, to validate that the correct values are being passed through to the callback and also consider (b) adding some other UI component to confirm that the app was being rendered.
The app is being rendered; for example, if I change the input type from hidden and type something into the textbox it does appear below. what do you mean by (a)?
app = DjangoDash('tutorial_1')
app.layout = html.Div([
dcc.Input(id='target_id', type = 'hidden'),
html.Div(id="output-one")
])
@app.expanded_callback(
dash.dependencies.Output('output-one','children'),
[dash.dependencies.Input('target_id','value')]
)
def callback_c(value, *args,**kwargs):
print(value)
return value
if __name__ == '__main__':
app.run_server(debug=True)
could you give me a simple example of an app that should be able to pick up the context from the template and display a number? like, if the view passed:
return render(request, 'model_results.html', {"context":'{"target_id": {"value": 67}}'})
to the template, and the template passed it to the app, what would be most simple app possible be that would display the number 67? if i could get it that far I can take it from there
@redtensor22 in the second demo there is an example of doing this with the content in the template. If your view passed something like
# This is a json string
init_vars = '{"context":'{"target_id": {"value": 67}}'
# Third arg is python dict of variables
return render(request, 'model_results.html', {'init_vars': init_vars})
and then in the template you had something like
{%plotly_app slug="tutorial-1" initial_arguments='{{init_vars}}' %}
you should get what you're looking forward. Disclaimer: just typed this in, haven't been able to validate it.
I'm having trouble with the actual app, and getting the variable. I'm using the above as provided and dont get any errors, but nothing appears in the dashboard
<div class="col-lg-1 col-md-1 col-xl-1 col-sm-1">
<div class = "card">
<div class = "card-body">
{%plotly_app name="tutorial_1" initial_arguments='{"target_id": {"value": "67"}}' %}
</div>
</div>
</div>
</div>
app = DjangoDash('tutorial_1')
app.layout = html.Div([
dcc.Input(id='target_id', persistence=False, value="test"),
html.Div(id="output-one")
])
@app.expanded_callback(
dash.dependencies.Output('output-one','children'),
[dash.dependencies.Input('target_id','value')]
)
def callback_c(*args,**kwargs):
print(value)
return value
if __name__ == '__main__':
app.run_server(debug=True)
but the output is not appearing in the app. Is my app code correct? I just need that dang number 67 to pop up in my app :((((
for anyone reading in the future, I was able to get this to work using some different code:
{%plotly_app name="tutorial_1" initial_arguments='{"dropdown-color": {"value": "red"}}' %}
app = DjangoDash('tutorial_1')
app.layout = html.Div([
dcc.RadioItems(
id='dropdown-color',
options=[{'label': c, 'value': c.lower()} for c in ['Red', 'Green', 'Blue']],
value='red'
),
html.Div(id='output-color'),
dcc.RadioItems(
id='dropdown-size',
options=[{'label': i, 'value': j} for i, j in [('L', 'large'),
('M', 'medium'),
('S', 'small')]],
value='medium'
),
html.Div(id='output-size')
])
@app.callback(
dash.dependencies.Output('output-color', 'children'),
[dash.dependencies.Input('dropdown-color', 'value')])
def callback_color(dropdown_value):
'Change output message'
return "The selected color is %s." % dropdown_value
@app.callback(
dash.dependencies.Output('output-size', 'children'),
[dash.dependencies.Input('dropdown-color', 'value'),
dash.dependencies.Input('dropdown-size', 'value')])
def callback_size(dropdown_color, dropdown_size):
'Change output message'
return "The chosen T-shirt is a %s %s one." %(dropdown_size,
dropdown_color)
Hi, I too am trying to get this done, I am getting error in :
response = get_response(request) …
| Django Version: | 3.2.13 |
|---|---|
| TypeError | |
| model_view() missing 1 required positional argument: 'pk' | |
| /home/filer/avig/dj/conda39/envs/dj_env/lib/python3.9/site-packages/django/core/handlers/base.py, line 181, in _get_response | |
| /home/filer/avig/dj/conda39/envs/dj_env/bin/python3 |