Black Lives Matter. Please consider donating to Black Girls Code today.

Django_plotly_dash can't get it to work

Hi,

I would like some help on how to get the django_plotly_dash working properly. I’ve followed the basic setup as instructed here for the django-plotly-dash library. However, the plotly component does not show up, and instead I’m getting a “127.0.0.1 refused to connect” error on the webpage.

Inspecting the error item shows that

<iframe src="/django_plotly_dash/app/SimpleEx/" style="
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    " frameborder="0"></iframe>

And entering the URL http://127.0.0.1:8000/django_plotly_dash/app/SimpleEx/
I’m actually able to see the plotly component…

So how can I get the plotly component to show up in the page I specify instead of the /django_plotly_dash/app/SimpleEx/?

Any help is appreciated, thank you in advance!
Jz

What sort of error do you see, if any, from the server when you get the connection error?

Refused to connect errors are generally caused by the server not running - which doesn’t seem to be the case here - or a problem with the client configuration. What is the “error item” that you are inspecting that contains the iframe content?

Hi delsim,

Below is the error code within that iframe. Thanks!

<body id="t" style="font-family: 'Segoe UI', Tahoma, sans-serif; font-size: 75%" jstcache="0" class="neterror">
  <div id="main-frame-error" class="interstitial-wrapper" jstcache="0">
    <div id="main-content" jstcache="0">
      <div class="icon icon-generic" jseval="updateIconClass(this.classList, iconClass)" alt="" jstcache="1"></div>
      <div id="main-message" jstcache="0">
        <h1 jstcache="0">
          <span jsselect="heading" jsvalues=".innerHTML:msg" jstcache="10"><span jscontent="hostName" jstcache="23">localhost</span> is blocked</span>
          <a id="error-information-button" class="hidden" onclick="toggleErrorInformationPopup();" jstcache="0"></a>
        </h1>
        <p jsselect="summary" jsvalues=".innerHTML:msg" jstcache="2"><strong jscontent="hostName" jstcache="23">localhost</strong> refused to connect.</p>
        <!--The suggestion list and error code are normally presented inline,
          in which case error-information-popup-* divs have no effect. When
          error-information-popup-container has the use-popup-container class, this
          information is provided in a popup instead.-->
        <div id="error-information-popup-container" jstcache="0">
          <div id="error-information-popup" jstcache="0">
            <div id="error-information-popup-box" jstcache="0">
              <div id="error-information-popup-content" jstcache="0">
                <div id="suggestions-list" style="display:none" jsdisplay="(suggestionsSummaryList &amp;&amp; suggestionsSummaryList.length)" jstcache="17">
                  <p jsvalues=".innerHTML:suggestionsSummaryListHeader" jstcache="19"></p>
                  <ul jsvalues=".className:suggestionsSummaryList.length == 1 ? 'single-suggestion' : ''" jstcache="20">
                    <li jsselect="suggestionsSummaryList" jsvalues=".innerHTML:summary" jstcache="22"></li>
                  </ul>
                </div>
                <div class="error-code" jscontent="errorCode" jstcache="18">ERR_BLOCKED_BY_RESPONSE</div>
                <p id="error-information-popup-close" jstcache="0">
                  <a class="link-button" jscontent="closeDescriptionPopup" onclick="toggleErrorInformationPopup();" jstcache="21">null</a>
                </p>
              </div>
            </div>
          </div>
        </div>
        <div id="diagnose-frame" class="hidden" jstcache="0"></div>
        <div id="download-links-wrapper" class="hidden" jstcache="0">
          <div id="download-link-wrapper" jstcache="0">
            <a id="download-link" class="link-button" onclick="downloadButtonClick()" jsselect="downloadButton" jscontent="msg" jsvalues=".disabledText:disabledMsg" jstcache="7" style="display: none;">
            </a>
          </div>
          <div id="download-link-clicked-wrapper" class="hidden" jstcache="0">
            <div id="download-link-clicked" class="link-button" jsselect="downloadButton" jscontent="disabledMsg" jstcache="12" style="display: none;">
            </div>
          </div>
        </div>
        <div id="save-page-for-later-button" class="hidden" jstcache="0">
          <a class="link-button" onclick="savePageLaterClick()" jsselect="savePageLater" jscontent="savePageMsg" jstcache="11" style="display: none;">
          </a>
        </div>
        <div id="cancel-save-page-button" class="hidden" onclick="cancelSavePageClick()" jsselect="savePageLater" jsvalues=".innerHTML:cancelMsg" jstcache="5" style="display: none;">
        </div>
        <div id="offline-content-list" class="list-hidden" hidden="" jstcache="0">
          <div id="offline-content-list-visibility-card" onclick="toggleOfflineContentListVisibility(true)" jstcache="0">
            <div id="offline-content-list-title" jsselect="offlineContentList" jscontent="title" jstcache="13" style="display: none;">
            </div>
            <div jstcache="0">
              <div id="offline-content-list-show-text" jsselect="offlineContentList" jscontent="showText" jstcache="15" style="display: none;">
              </div>
              <div id="offline-content-list-hide-text" jsselect="offlineContentList" jscontent="hideText" jstcache="16" style="display: none;">
              </div>
            </div>
          </div>
          <div id="offline-content-suggestions" jstcache="0"></div>
          <div id="offline-content-list-action" jstcache="0">
            <a class="link-button" onclick="launchDownloadsPage()" jsselect="offlineContentList" jscontent="actionText" jstcache="14" style="display: none;">
            </a>
          </div>
        </div>
      </div>
    </div>
    <div id="buttons" class="nav-wrapper suggested-left" jstcache="0">
      <div id="control-buttons" hidden="" jstcache="0">
        <button id="reload-button" class="blue-button text-button" onclick="trackClick(this.trackingId);
                     reloadButtonClick(this.url);" jsselect="reloadButton" jsvalues=".url:reloadUrl; .trackingId:reloadTrackingId" jscontent="msg" jstcache="6" style="display: none;"></button>
        <button id="download-button" class="blue-button text-button" onclick="downloadButtonClick()" jsselect="downloadButton" jscontent="msg" jsvalues=".disabledText:disabledMsg" jstcache="7" style="display: none;">
        </button>
      </div>
      <button id="details-button" class="secondary-button text-button small-link singular" onclick="detailsButtonClick(); toggleHelpBox()" jscontent="details" jsdisplay="(suggestionsDetails &amp;&amp; suggestionsDetails.length > 0) || diagnose" jsvalues=".detailsText:details; .hideDetailsText:hideDetails;" jstcache="3" style="display: none;"></button>
    </div>
    <div id="details" class="hidden" jstcache="0">
      <div class="suggestions" jsselect="suggestionsDetails" jstcache="4" jsinstance="*0" style="display: none;">
        <div class="suggestion-header" jsvalues=".innerHTML:header" jstcache="8"></div>
        <div class="suggestion-body" jsvalues=".innerHTML:body" jstcache="9"></div>
      </div>
    </div>
  </div>
  <div id="sub-frame-error" jstcache="0">
    <!-- Show details when hovering over the icon, in case the details are
         hidden because they're too large. -->
    <div class="icon icon-generic" jseval="updateIconClass(this.classList, iconClass)" jstcache="1"></div>
    <div id="sub-frame-error-details" jsselect="summary" jsvalues=".innerHTML:msg" jstcache="2"><strong jscontent="hostName" jstcache="23">localhost</strong> refused to connect.</div>
  </div>

I should have been more explicit: what error, if any, is reported from the server process (and not the content returned to the client) when the ‘refused to connect’ error is generated?

Sorry that I misunderstood your question. I’m teaching myself Python so thank you for bearing with me.

From the server side I don’t see any error message…

image

Maybe it helps if I post my code here. I realize that posting just the error message might be difficult for debugging. I really appreciate you taking the time to look into this.

settings.py


import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'j#s!^*8o$sg4uy+o^dnq-3g1ef2!ka(zbz)5tbtn!*vbn0@&b2'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django_plotly_dash.apps.DjangoPlotlyDashConfig',
    'survey.apps.SurveyConfig',
    'crispy_forms',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

CRISPY_TEMPLATE_PACK = 'bootstrap4'

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    
    
    'django_plotly_dash.middleware.BaseMiddleware',
    'django_plotly_dash.middleware.ExternalRedirectionMiddleware',

    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'site_1.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'site_1.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/

STATIC_URL = '/static/'


PLOTLY_COMPONENTS = [
    'dash_core_components',
    'dash_html_components',
    'dash_bootstrap_components',
    'dash_renderer',
    'dpd_components',
    'dpd_static_support',
]

Project urls.py

from django.contrib import admin
from django.urls import path, include
from survey import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('survey/', include('survey.urls')),
    path('django_plotly_dash/', include('django_plotly_dash.urls')),
]

App’s urls.py

from django.urls import path
from . import views

from . import app
from . import simple_app


urlpatterns = [
    path('', views.get_survey_2, name = 'survey'),

]

views.py

def get_survey_2(request):
    
    if request.method == "POST":
        form = SurveyModelForm(request.POST)

        print(form.is_valid())
        print(form.cleaned_data)
        print(form.errors)

        if form.is_valid():
            print('form save')
            form.save()

            #return HttpResponseRedirect('/thanks/')
            return render(request, 'thanks.html')
            

    else:
        form = SurveyModelForm(initial = {'city':'Toronto'})
    return render(request, 'survey_home.html', {'form':form})

survey_home.html

{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% load plotly_dash %}

{% block content %}
    {% plotly_app name="app1" %}
{% endblock content %}

app.py

import dash
import dash_core_components as dcc
import dash_html_components as html
from django_plotly_dash import DjangoDash

app = DjangoDash('app1')


#external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

colors = {
    'background': '#111111',
    'text': '#7FDBFF'
}

app.layout = html.Div(style={'backgroundColor':colors['background']}, children=[
    html.H1(
        children='Hello Dash',
        style={
            'textAlign':'center',
            'color': colors['text']

        }
        ), 
    # The html.H1(children='Hello Dash') component generates a 
    # <h1>Hello Dash</h1> HTML element in your application.

    html.Div(children='Dash: A web application framework for Python.', style = {'textAlign':'center','color':colors['text']}),

    dcc.Graph(
        id='example-graph',
        figure={
            'data': [
                {'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': 'SF'},
                {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': u'Montréal'},
            ],
            'layout': {
                'plot_bgcolor': colors['background'],
                'paper_bgcolor': colors['background'],
                'font':{'color' : colors['text']},
                'title': 'Dash Data Visualization'
            }
        }
    )
])

So the issue is you’re using Django 3.0, which has settings that prevent the use of iframes by default.

See this issue where the problem is reported, and also contains some alternative resolutions. These boil down to either using Django 2.2 for the moment - probably easiest if you do not need any of the features of 3.0 - or adding a setting for X_FRAME_OPTIONS to your settings file.

1 Like

Hi delsim,

I’m happy to report that the issue was fixed and really appreciate your help with my questions.

I thought that maybe one of the dependencies was missing so I was literally manually re-installing all the packages one-by-one, you have saved me hours of work!

I tested on Django 2.2 and it did work. Then I switched back to Django 3.0 again, and put
X_FRAME_OPTIONS = 'SAMEORIGIN'
in the settings.py file and now it works as well.

This library is super cool and I can’t wait to use it for my first real Django project. Thanks again!
-Jz