diff --git a/.gitignore b/.gitignore index 1d45c5b1..94c798eb 100644 --- a/.gitignore +++ b/.gitignore @@ -54,6 +54,7 @@ coverage.xml *.log local_settings.py */db.sqlite3 +demo/static/* # Flask stuff: instance/ diff --git a/README.md b/README.md index 245ac841..6aeecd01 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,6 @@ See the source for this project here: This README file provides a short guide to installing and using the package, and also outlines how to run the demonstration application. - - More detailed information can be found in the online documentation at @@ -105,5 +103,5 @@ templates: The registration code needs to be in a location that will be imported into the Django process before any model or template tag attempts to use it. The example Django application -in the demo subdirectory achieves this through an import in the main urls.py file; any views.py would also be sufficient. +in the demo subdirectory achieves this through an import in the main `urls.py` file; any `views.py` would also be sufficient. diff --git a/demo/demo/settings.py b/demo/demo/settings.py index d26e9373..2371cc06 100644 --- a/demo/demo/settings.py +++ b/demo/demo/settings.py @@ -120,3 +120,13 @@ # https://docs.djangoproject.com/en/2.0/howto/static-files/ STATIC_URL = '/static/' +STATIC_ROOT = os.path.join(BASE_DIR,'static') + +STATICFILES_DIRS = [ + ] + +import dash_core_components as dcc +_rname = os.path.join(os.path.dirname(dcc.__file__),'..') +for dash_module_name in ['dash_core_components','dash_html_components','dash_renderer',]: + STATICFILES_DIRS.append( ("dash/%s"%dash_module_name, os.path.join(_rname,dash_module_name)) ) + diff --git a/django_plotly_dash/__init__.py b/django_plotly_dash/__init__.py index 86cba23d..36a143b7 100644 --- a/django_plotly_dash/__init__.py +++ b/django_plotly_dash/__init__.py @@ -1,6 +1,6 @@ # -__version__ = "0.1.0" +__version__ = "0.2.0" from .dash_wrapper import DjangoDash diff --git a/django_plotly_dash/dash_wrapper.py b/django_plotly_dash/dash_wrapper.py index e3572df9..b1c4af39 100644 --- a/django_plotly_dash/dash_wrapper.py +++ b/django_plotly_dash/dash_wrapper.py @@ -72,17 +72,30 @@ def have_current_state_entry(self, wid, key): 'Do nothing impl - only matters if state present' pass - def form_dash_instance(self, replacements=None, specific_identifier=None): + def get_base_pathname(self, specific_identifier): if not specific_identifier: app_pathname = "%s:app-%s"% (app_name, main_view_label) + ndid = self._uid else: app_pathname="%s:%s" % (app_name, main_view_label) + ndid = specific_identifier + + try: + full_url = reverse(app_pathname,kwargs={'id':ndid}) + except: + full_url = "/%s/" %ndid + + return ndid, full_url + + def form_dash_instance(self, replacements=None, specific_identifier=None): - rd = NotDash(name_root=self._uid, - app_pathname=app_pathname, + ndid, base_pathname = self.get_base_pathname(specific_identifier) + + rd = NotDash(base_pathname=base_pathname, expanded_callbacks = self._expanded_callbacks, replacements = replacements, - specific_identifier = specific_identifier) + ndid = ndid) + rd.layout = self.layout for cb, func in self._callback_sets: @@ -126,22 +139,24 @@ def run(self,*args,**kwargs): pass class NotDash(Dash): - def __init__(self, name_root, app_pathname=None, replacements = None, specific_identifier=None, expanded_callbacks=False, **kwargs): + def __init__(self, base_pathname=None, replacements = None, ndid=None, expanded_callbacks=False, **kwargs): - if specific_identifier is not None: - self._uid = specific_identifier - else: - self._uid = name_root + self._uid = ndid self._flask_app = Flask(self._uid) self._notflask = NotFlask() - self._base_pathname = reverse(app_pathname,kwargs={'id':self._uid}) + self._base_pathname = base_pathname kwargs['url_base_pathname'] = self._base_pathname kwargs['server'] = self._notflask super(NotDash, self).__init__(**kwargs) + self.css.config.serve_locally = True + #self.css.config.serve_locally = False + + self.scripts.config.serve_locally = self.css.config.serve_locally + self._adjust_id = False self._dash_dispatch = not expanded_callbacks if replacements: @@ -158,8 +173,7 @@ def use_dash_layout(self): def augment_initial_layout(self, base_response): if self.use_dash_layout() and False: - return HttpResponse(base_response.data, - content_type=base_response.mimetype) + return base_response.data, base_response.mimetype # Adjust the base layout response baseDataInBytes = base_response.data baseData = json.loads(baseDataInBytes.decode('utf-8')) @@ -167,8 +181,8 @@ def augment_initial_layout(self, base_response): reworked_data = self.walk_tree_and_replace(baseData) response_data = json.dumps(reworked_data, cls=PlotlyJSONEncoder) - return HttpResponse(response_data, - content_type=base_response.mimetype) + + return response_data, base_response.mimetype def walk_tree_and_extract(self, data, target): if isinstance(data, dict): diff --git a/django_plotly_dash/urls.py b/django_plotly_dash/urls.py index dc81954f..0e1a65c6 100644 --- a/django_plotly_dash/urls.py +++ b/django_plotly_dash/urls.py @@ -1,7 +1,7 @@ from django.urls import path from django.views.decorators.csrf import csrf_exempt -from .views import routes, layout, dependencies, update, main_view +from .views import routes, layout, dependencies, update, main_view, component_suites from .app_name import app_name, main_view_label @@ -11,11 +11,13 @@ path('instance/_dash-dependencies', dependencies, name="dependencies"), path('instance/_dash-update-component', csrf_exempt(update), name="update-component"), path('instance/', main_view, name=main_view_label), + path('instance/_dash-component-suites//', component_suites, name='component-suites'), path('app/_dash-routes', routes, {'stateless':True}, name="app-routes"), path('app/_dash-layout', layout, {'stateless':True}, name="app-layout"), path('app/_dash-dependencies', dependencies, {'stateless':True}, name="app-dependencies"), path('app/_dash-update-component', csrf_exempt(update), {'stateless':True}, name="app-update-component"), path('app/', main_view, {'stateless':True}, name='app-%s'%main_view_label), + path('app/_dash-component-suites//', component_suites, {'stateless':True}, name='app-component-suites'), ] diff --git a/django_plotly_dash/views.py b/django_plotly_dash/views.py index abd73ebb..2c48462c 100644 --- a/django_plotly_dash/views.py +++ b/django_plotly_dash/views.py @@ -1,5 +1,5 @@ from django.shortcuts import render, get_object_or_404 -from django.http import HttpResponse +from django.http import HttpResponse, HttpResponseRedirect import json @@ -22,7 +22,9 @@ def layout(request, id, stateless=False, **kwargs): mFunc = app.locate_endpoint_function('dash-layout') resp = mFunc() - return app.augment_initial_layout(resp) + response_data, mimetype = app.augment_initial_layout(resp) + return HttpResponse(response_data, + content_type=mimetype) def update(request, id, stateless=False, **kwargs): da, app = DashApp.locate_item(id, stateless) @@ -59,3 +61,12 @@ def main_view(request, id, stateless=False, **kwargs): resp = mFunc() return HttpResponse(resp) +def component_suites(request, resource=None, component=None, **kwargs): + + eBig = request.GET.urlencode() + if len(eBig) > 0: + redone_url = "/static/dash/%s/%s?%s" %(component, resource, eBig) + else: + redone_url = "/static/dash/%s/%s" %(component, resource) + + return HttpResponseRedirect(redirect_to=redone_url) diff --git a/docs/index.rst b/docs/index.rst index ce6f4727..ee570af4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -22,9 +22,3 @@ Contents models_and_state -Indices and tables ------------------- - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/prepare_demo b/prepare_demo index 2312ea7d..5023168a 100755 --- a/prepare_demo +++ b/prepare_demo @@ -4,4 +4,5 @@ source env/bin/activate cd demo ./manage.py migrate ./manage.py shell < configdb.py # Add a superuser if needed +./manage.py collectstatic -i "*.py" -i "*.pyc" --noinput --link ./manage.py runserver