Dash & Django -- passing variable across apps

I have a survey application built in Django where consultants are able to sign into a profile which gives them the ability to launch a new survey, monitor progress and visualize the results. I would like to use Dash to visualize the results.

This survey is long and is thus divided into sections. Each section has its own table. Each row contains a primary key which can be used to identify the company each respondent belongs to.

From the consultant’s profile page (Django), a user can click a link called “Dashboard” and Dash is launched following Ead’s Method.

My question is simply, what is the best way to bring this primary key (attached to the button) along with the user when they navigate through to Dash. This key is required to filter the visualization’s down.

I have attempted solutions with an Ajax post and passing the key along with the URL. I’m having trouble turning that JS var into python on dashapp and once user navigates from the original url, I lose the key.

What is the appropriate way to access a button value when clicked in a pure Django app within Dash app running in a Django app?

I believe there must be a simple answer to this.

My company is behind django-plotly-dash which provides, along with other functionality, a plotly_app template tag that passes initial arguments through to a Dash app.

This might be of use to you, or the code might provide you with useful pointers. I do recall that there is a bit of work that needs to be done to add the extra values to the application state.

Hi!

I am quite new to web-development and lack knowledge of concepts; therefore, I sincerely apologize if the question that I outlined further had been asked already, or if it is a very basic one. I use django-plotly-dash package to integrate Dash application and I am constantly facing mistake when trying to replace default dataset in Dash data table with data in “initial arguments” tag.

I use Dash data table to visualize a pivot table that is derived from backend calculations of values in the database. Further, I need to enable a user the option to filter rendered data based on certain database attributes. For that I created a class-based view with a filter that feeds an html template with values in a form of a dictionary, which I consequently use to populate the “initial arguments”.

The error I am receiving originates from “raise JSONDecodeError(“Expecting value”, s, err.value) from None”. And when I use initial unfiltered dataset, it is rendered well.

I am lost in trying to understand what am I doing wrong. Could you please advise on how should I approach the solution?

There are two places to look first - how you are forming the initial arguments, and how they are being passed to the template. At least one of these has to vary what it does based on the filtering - this is where I would look first. Without sight of the code its hard to comment further.

@delsim, thank you for your fast reply!

Please find below the sections of my code that I use for creating a specified outcome.
Could you please comment if you see there anything that is strange/ wrong?

Thank you for your support!

++++++++++++++++++++++++++++++++++++

View:
class HomePageView(ListView, JSONResponseMixin):
model = MyModel
filter_class = MyFilter
formhelper_class = MyListFormHelper
template_name = “view_data/home_view.html”
context_object_name = ‘dash_inputs’
context_filter_name = ‘filter’

def get_queryset(self, **kwargs):
    qs = super(ListView, self).get_queryset()
    self.filter = self.filter_class(self.request.GET, queryset=qs)
    self.filter.form.helper = self.formhelper_class()
    pivot_table = pivot(self.filter.qs, ['parameter1', 'parameter2'], 'timeref', 'value') ###the resulting object is Django Queryset###
    df = read_frame(pivot_table)
    df = df.round(0)
    df = df.to_dict('records')
    mydict = {}
    mydict['id'] = 'table'
    mydict['data'] = df
    return mydict

def get_context_data(self, **kwargs):
    context = super(ListView, self).get_context_data()
    context[self.context_filter_name] = self.filter
    return context 

++++++++++++++++++++++++++++++++++++

Default data:
qs = MyModel.objects.values(‘parameter1’, ‘parameter2’, ‘timeref’, ‘value’).exclude(parameter1=None).exclude(parameter2=None)
pivot_table = pivot(self.filter.qs, [‘parameter1’, ‘parameter2’], ‘timeref’, ‘value’)
df = read_frame(pivot_table)
df = df.round(0)

Dash app:
app = DjangoDash(‘SimpleExample’, external_stylesheets=external_stylesheets) # replaces dash.Dash
app.layout = html.Div([
dash_table.DataTable(
id=‘table’,
columns=[{“name”: i, “id”: i} for i in df.columns],
data=df.to_dict(‘records’),
style_data_conditional=[
{
‘if’: {‘row_index’: ‘odd’},
‘backgroundColor’: ‘rgb(235, 235, 235)’
},
],
style_cell_conditional=[
{
‘if’: {‘column_id’: ‘parameter1’},
‘minWidth’: ‘180px’, ‘width’: ‘180px’, ‘maxWidth’: ‘180px’,
‘textAlign’: ‘center’
},
{
‘if’: {‘column_id’: ‘parameter2’},
‘minWidth’: ‘180px’, ‘width’: ‘180px’, ‘maxWidth’: ‘180px’,
‘textAlign’: ‘center’
}
],
css=[{
‘selector’: ‘.dash-cell div.dash-cell-value’,
‘rule’: ‘display: inline; white-space: inherit; overflow: inherit; text-overflow: inherit;’
}],
style_cell={
‘whiteSpace’: ‘no-wrap’,
‘overflow’: ‘hidden’,
‘textOverflow’: ‘ellipsis’,
},
style_header={
‘backgroundColor’: ‘rgb(230, 230, 230)’,
‘fontWeight’: ‘bold’
},
),
])

++++++++++++++++++++++++++++++++++++

Template:
{%load plotly_dash%}


{%plotly_app name=“SimpleExample” initial_arguments=“dash_inputs” ratio=1%}

Its not obvious to me that dash_inputs contains the appropriate values; your get_queryset function isn’t returning a queryset.
One test would be to just have the template dump out the contents of the variable by using {{dash_inputs}} or similar and working from there.

Hi, @delsim!

Thank you for your tip, it heped me to understand where the problem was!
Indeed there was a problem in a way I tried to form the dictionary, which was not corresponding to the syntax described in a demo. I have modified a part of the code in get_queryset in the following way:

    mydict = {}
    mydict['table'] = {}
    mydict['table']['data'] = df

And it worked then!

I have another challenge though, I try to pass data from my dash table to the graph through “app.expanded_callback” and when I render the page the graph is empty. Could you please advice on what could be wrong? The code is below. Thanks a lot!

++++++++++++++++++++++++++++++++++++

Dash app:

    app = DjangoDash(‘SimpleExample’, external_stylesheets=external_stylesheets) # replaces dash.Dash
    app.layout = html.Div([
    dash_table.DataTable(
    id=‘table’,
    columns=[{“name”: i, “id”: i} for i in df.columns],
    data=df.to_dict(‘records’),
    style_data_conditional=[
    {
    ‘if’: {‘row_index’: ‘odd’},
    ‘backgroundColor’: ‘rgb(235, 235, 235)’
    },
    ],
    style_cell_conditional=[
    {
    ‘if’: {‘column_id’: ‘parameter1’},
    ‘minWidth’: ‘180px’, ‘width’: ‘180px’, ‘maxWidth’: ‘180px’,
    ‘textAlign’: ‘center’
    },
    {
    ‘if’: {‘column_id’: ‘parameter2’},
    ‘minWidth’: ‘180px’, ‘width’: ‘180px’, ‘maxWidth’: ‘180px’,
    ‘textAlign’: ‘center’
    }
    ],
    css=[{
    ‘selector’: ‘.dash-cell div.dash-cell-value’,
    ‘rule’: ‘display: inline; white-space: inherit; overflow: inherit; text-overflow: inherit;’
    }],
    style_cell={
    ‘whiteSpace’: ‘no-wrap’,
    ‘overflow’: ‘hidden’,
    ‘textOverflow’: ‘ellipsis’,
    },
    style_header={
    ‘backgroundColor’: ‘rgb(230, 230, 230)’,
    ‘fontWeight’: ‘bold’
    },
    ),
        dcc.Graph(id='graph'),
    ])
    
    @app.expanded_callback(
        dash.dependencies.Output('graph', 'figure'),
        [dash.dependencies.Input('table', 'data'),
         dash.dependencies.Input('table', 'columns')])
    def display_output(rows, columns):
        return {
            'data': [{
                'type': 'bar',
                'z': [[row.get(c['id'], None) for c in columns] for row in rows],
                'x': [c['name'] for c in columns]
            }]
        }

++++++++++++++++++++++++++++++++++++

Template:
{%load plotly_dash%}

{%plotly_app name=“SimpleExample” initial_arguments=“dash_inputs” ratio=1%}

There is nothing that immediately jumps out as wrong to me, from a quick scan of the code.

Have you tried adding a print statement (or some other logging call) inside your callback to look at the inputs and also the response generated for the graph? That should help pinpoint the issue.

you need to remove the string around your data set like
{%plotly_app name=“SimpleExample” initial_arguments=dash_inputs ratio=1%}