{ "info": { "author": "Artur Barseghyan", "author_email": "artur.barseghyan@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Web Environment", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", "License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)", "Operating System :: OS Independent", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6" ], "description": "===========\ndjango-dash\n===========\n``django-dash`` (later on named Dash) is a customisable, modular dashboard\napplication framework for Django.\n\nDash allows users to create their own custom dashboards. Supports theeming (in\nDash themes are called layouts) and multiple workspaces. Dash comes with\nextensive pythonic API which allows developers to create new Dash plugins, as\nwell as to modify bundled ones.\n\nTo make a clearer association, think of Android for tablets (shortcuts, widgets\nand apps) or Windows 8 for tablets or desktops.\n\nDash inherits all those concepts and makes it possible to implement a dashboard\nsystem for Django applications with minimal efforts.\n\nPrerequisites\n=============\nPresent\n-------\n- Django 1.8, 1.9, 1.10, 1.11, 2.0\n- Python >=2.7, >=3.4\n\nPast\n----\n- Dropping support of Django 1.5, 1.6 and 1.7 has been announced in version\n 0.5. As of 0.5 everything is still backwards compatible with above mentioned\n versions , but in future versions compatibility with these versions will be\n wiped out.\n- Support of Python 2.6 has been dropped in version 0.5.\n\nKey concepts\n============\n- Each layout (theme) consist of placeholders. Each plugin widget has its' own\n specific HTML/JavaScript/CSS.\n- There might be multiple themes implemented and installed. Default layout is \n chosen system wide, but each user (if has an appropriate permission) can\n choose his preferred layout over all workspaces or even different layouts \n per workspace.\n- Placeholder is a space, in which the plugin widgets are placed.\n- Placeholders are rectangles consisting of cells. Each placeholder has its' \n own custom number of rows and columns.\n- Workspace is just another named dashboard. Users switch between workspaces \n in navigation. Amount of workspaces is unlimited.\n- Plugin is a (Django) micro app. Most heavy work should happen in plugin. \n Plugin may have its' own views, urls, etc. Rendering happens with use of\n plugin widgets.\n- Plugin widgets are mainly responsible for rendering of the plugin data. \n Each plugin widget has its' own specific HTML/JavaScript/CSS. A single\n plugin widget is registered for a triple (layout, placeholder, plugin).\n- Public dashboard (implemented as a contrib app, which makes it optional)\n allows users to make their workspaces public. If user chooses to make his\n dashboard public, default workspace becomes public. As for non-default\n workspaces, user can still make each of them private or public.\n\nMain features\n=============\n- Customisable layouts (aka theeming).\n- Multiple workspaces.\n- Tunable access permissions to plugins.\n- Public dashboards (as a contrib app).\n- Cloneable workspaces. It's possible to clone entire workspace, including\n all the plugins into another workspace.\n- Copy/paste functionality for plugin widgets.\n\nFAQ\n===\n- Question: Is it possible to have Dash working with a (pick what's applicable: \n D3, Polychart2, or some other library for making charts).\n\n Answer: Yes. Check the source code of the following sample plugins:\n\n - `Sample D3 plugins\n `_.\n - `Sample Polychart2 plugin\n `_.\n\nSome screenshots\n================\nSee the documentation for some screen shots:\n\n- `PythonHosted `_\n- `ReadTheDocs `_\n\nDemo\n====\nLive demo\n---------\nSee the `live demo app `_ on Heroku.\n\nCredentials:\n\n- username: test_user\n- password: test_user\n\nSee the public dashboard of a `test_demo_user\n`_ to get an idea of what\nit could become.\n\nRun demo locally\n----------------\nIn order to be able to quickly evaluate the `django-dash`, a demo app (with a\nquick installer) has been created (works on Ubuntu/Debian, may work on other\nLinux systems as well, although not guaranteed). Follow the instructions\nbelow for having the demo running within a minute.\n\nGrab the latest ``django_dash_example_app_installer.sh``:\n\n.. code-block:: sh\n\n wget https://raw.github.com/barseghyanartur/django-dash/stable/examples/django_dash_example_app_installer.sh\n\nAssign execute rights to the installer and run the\n``django_dash_example_app_installer.sh``:\n\n.. code-block:: sh\n\n chmod +x django_dash_example_app_installer.sh\n\n ./django_dash_example_app_installer.sh\n\nOpen your browser and test the app.\n\nDashboard:\n\n- URL: http://127.0.0.1:8001/en/dashboard/\n- Admin username: test_admin\n- Admin password: test\n\nDjango admin interface:\n\n- URL: http://127.0.0.1:8001/en/administration/\n- Admin username: test_admin\n- Admin password: test\n\nIf quick installer doesn't work for you, see the manual steps on running the\n`example project\n`__.\n\nTake a look at the templates in \"example/example/templates\" directory for\ngetting a better idea of how to transform your own or third-party templates\ninto Dash templates.\n\nAlso, the `example project\n`__\nhas example layouts, plugins and widgets implemented. Take it as a good example\nof how to add widgets for existing plugins to your own custom layout.\nMake sure to see how same is done for the `bundled layouts\n`_.\n\nInstallation\n============\n1. Install latest stable version from PyPI:\n\n .. code-block:: sh\n\n pip install django-dash\n\n Or latest stable version from GitHub:\n\n .. code-block:: sh\n\n pip install https://github.com/barseghyanartur/django-dash/archive/stable.tar.gz\n\n Or latest stable version from BitBucket:\n\n .. code-block:: sh\n\n pip install https://bitbucket.org/barseghyanartur/django-dash/get/stable.tar.gz\n\n2. Add `dash` to ``INSTALLED_APPS`` of the your projects' Django settings.\n Furthermore, all layouts and plugins to be used, shall be added to the\n ``INSTALLED_APPS`` as well.\n\n .. code-block:: python\n\n INSTALLED_APPS = (\n # ...\n 'dash',\n 'dash.contrib.layouts.android',\n 'dash.contrib.layouts.bootstrap2',\n 'dash.contrib.layouts.windows8',\n 'dash.contrib.plugins.dummy',\n 'dash.contrib.plugins.image',\n 'dash.contrib.plugins.memo',\n 'dash.contrib.plugins.rss_feed',\n 'dash.contrib.plugins.url',\n 'dash.contrib.plugins.video',\n 'dash.contrib.plugins.weather',\n # ...\n )\n\n3. Make sure that ``django.core.context_processors.request`` is in\n ``TEMPLATE_CONTEXT_PROCESSORS``.\n\n4. Add necessary URL patterns to your ``urls`` module.\n\n .. code-block:: python\n\n url(r'^dashboard/', include('dash.urls')),\n\n Additionally, add all URLs of any Dash apps or plugins\n\n .. code-block:: python\n\n # django-dash RSS contrib plugin URLs:\n url(r'^dash/contrib/plugins/rss-feed/',\n include('dash.contrib.plugins.rss_feed.urls')),\n\n # django-dash public dashboards contrib app:\n url(r'^', include('dash.contrib.apps.public_dashboard.urls')),\n\nCreating a new layout\n=====================\nDash comes with several bundled layouts. Do check their source code as example. \n\nLet's say, our imaginary layout has two placeholders. One large placeholder for\nall kinds of widgets (called ``main``) and a tiny one for shortcuts (called\n``shortcuts``).\n\nPlaceholder ``main``:\n\n- Single cell size : 150 x 110 pixels\n- Dimensions : 6 cols, 5 rows\n\nPlaceholder ``shortcuts``:\n\n- Single cell size : 60 x 55 pixels\n- Dimensions : 1 cols, 10 rows\n\nSee the figure below to get an idea of what placeholders are:\n\n- Placeholder ``main`` consts of cells from 11 to 56.\n- Placeholder ``shortcuts`` consists of cells from 1 to 10.\n\nA single plugin widget may occupy one or more cells. Plugin widgets are\nrectangles.\n\nTo make it clear, see following cases:\n\n- Plugin widget has 2 cols and 1 row. Then, for example, it may occupy cells\n (11 and 12).\n- Plugin widget has 2 cols and 2 rows. Then, for example, it may occupy cells \n (11, 12, 21 and 22).\n- Plugin widget has 1 col and 3 rows. Then, for example, it may occupy cells \n (11, 21 and 31).\n- Plugin widget has 4 cols and 3 rows. Then, for example, it may occupy cells \n (22, 23, 24, 25, 32, 33, 34, 35, 42, 43, 44 and 45).\n\n.. code-block:: text\n\n ``main`` ``shortcuts``\n \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2510\n \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 1 \u2502\n \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502\n \u2502 11 \u2502 12 \u2502 13 \u2502 14 \u2502 15 \u2502 16 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 2 \u2502\n \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502\n \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502\n \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 3 \u2502\n \u2502 21 \u2502 22 \u2502 23 \u2502 24 \u2502 25 \u2502 26 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 4 \u2502\n \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502\n \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502\n \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 5 \u2502\n \u2502 31 \u2502 32 \u2502 33 \u2502 34 \u2502 35 \u2502 36 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 6 \u2502\n \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502\n \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502\n \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 7 \u2502\n \u2502 41 \u2502 42 \u2502 43 \u2502 44 \u2502 45 \u2502 46 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 8 \u2502\n \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502\n \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502\n \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 9 \u2502\n \u2502 51 \u2502 52 \u2502 53 \u2502 54 \u2502 55 \u2502 56 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 10 \u2502\n \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2518\n\nThere are some rules/guidelines you should follow.\n\nLet's assume that layout is named ``example``. The layout directory should then\nhave the following structure.\n\n.. code-block:: text\n\n path/to/layout/example/\n \u251c\u2500\u2500 static\n \u2502\u00a0\u00a0 \u251c\u2500\u2500 css\n \u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u2514\u2500\u2500 dash_layout_example.css # Contains layout-specific CSS\n \u2502\u00a0\u00a0 \u251c\u2500\u2500 images\n \u2502\u00a0\u00a0 \u2514\u2500\u2500 js\n \u2502\u00a0\u00a0 \u2514\u2500\u2500 dash_layout_example.js # Contains layout specific JavaScripts\n \u251c\u2500\u2500 templates\n \u2502 \u2514\u2500\u2500 example\n \u2502 \u251c\u2500\u2500 edit_layout.html # Master edit layout\n \u2502 \u2514\u2500\u2500 view_layout.html # Master view layout\n \u251c\u2500\u2500 __init__.py\n \u251c\u2500\u2500 dash_layouts.py # Where layouts and placeholders are defined and registered\n \u251c\u2500\u2500 dash_plugins.py # Where layout specific plugins and plugin widgets are defined and registered\n \u2514\u2500\u2500 dash_widgets.py # Where layout specific plugin widgets are defined\n\nLayout and placeholder classes should be placed in the ``dash_layouts.py``\nfile.\n\nEach layout should be put into the ``INSTALLED_APPS`` of your Django projects'\n``settings.py`` module.\n\n.. code-block:: python\n\n INSTALLED_APPS = (\n # ...\n 'path.to.layout.example',\n # ...\n )\n\npath/to/layout/example/dash_layouts.py\n--------------------------------------\nStep by step review of a how to create and register a layout and placeholders.\nNote, that Dash auto-discovers your layouts by name of the file\n``dash_layouts.py``. The module, in which the layouts are defined, has to be\nnamed ``dash_layouts.py``.\n\nRequired imports.\n\n.. code-block:: python\n\n from dash.base import BaseDashboardLayout, BaseDashboardPlaceholder\n from dash.base import layout_registry\n\nDefining the Main placeholder.\n\n.. code-block:: python\n\n class ExampleMainPlaceholder(BaseDashboardPlaceholder):\n\n uid = 'main' # Unique ID of the placeholder.\n cols = 6 # Number of columns in the placeholder.\n rows = 5 # Number of rows in the placeholder.\n cell_width = 150 # Width of a single cell in the placeholder.\n cell_height = 110 # Height of a single cell in the placeholder.\n\nDefining the Shortcuts placeholder.\n\n.. code-block:: python\n\n class ExampleShortcutsPlaceholder(BaseDashboardPlaceholder):\n\n uid = 'shortcuts' # UID of the placeholder.\n cols = 1 # Number of columns in the placeholder.\n rows = 10 # Number of rows in the placeholder.\n cell_width = 60 # Width of a single cell in the placeholder.\n cell_height = 55 # Height of a single cell in the placeholder.\n\nDefining and registering the Layout.\n\n.. code-block:: python\n\n class ExampleLayout(BaseDashboardLayout):\n\n uid = 'example' # Layout UID.\n name = 'Example' # Layout name.\n\n # View template. Master template used in view mode.\n view_template_name = 'example/view_layout.html'\n\n # Edit template. Master template used in edit mode.\n edit_template_name = 'example/edit_layout.html'\n\n # All placeholders listed. Note, that placeholders are rendered in the\n # order specified here.\n placeholders = [ExampleMainPlaceholder, ExampleShortcutsPlaceholder]\n\n # Cell units used in the entire layout. Allowed values are: 'px',\n # 'pt', 'em' or '%'. In the ``ExampleMainPlaceholder`` cell_width is\n # set to 150. It means that in this particular case its' actual width\n # would be `150px`.\n cell_units = 'px'\n\n # Layout specific CSS.\n media_css = ('css/dash_layout_example.css',)\n\n # Layout specific JS.\n media_js = ('js/dash_layout_example.js',)\n\n # Registering the layout.\n layout_registry.register(ExampleLayout)\n\nHTML templates\n--------------\nYou custom layout should be inherited from base layout templates (view or\nedit). Both view and edit layouts share a lot of things, still edit layout is\na bit more \"heavy\".\n\n- view_layout.html should inherit from \"dash/layouts/base_view_layout.html\".\n- edit_layout.html should inherit from \"dash/layouts/base_edit_layout.html\".\n\nBoth \"dash/layouts/base_view_layout.html\" and\n\"dash/layouts/base_edit_layout.html\" inherit from\n\"dash/layouts/base_layout.html\", which in its' turn inherits from\n\"dash/base.html\".\n\nNote, that when rendered to HTML, each Dash template, gets a body class\n\"layout\" + layouts' unique identifier (UID). So, the ``ExampleLayout``\nlayout would automatically get the class \"layout-example\".\n\n.. code-block:: html\n\n \n\nIn case of Android layout (UID \"android\") it would be as follows.\n\n.. code-block:: html\n\n \n\nBase your layout specific custom CSS on presence of those classes.\n\nSame goes for Placeholders. Each placeholder gets ``id_`` + placeholders' UID\nand the classes \"placeholder\" and \"placeholder-\" + placeholders' UID. So, the\n``ExampleMainPlaceholder`` would look as follows.\n\n.. code-block:: html\n\n
\n\nAnd the ``ExampleShortcutsPlaceholder`` placeholder would look as follows.\n\n.. code-block:: html\n\n
\n\nSame goes for plugin widgets. Apart from some other classes that each plugin\nwidget would get for positioning, it gets the \"plugin\" and \"plugin-\" + plugin\nUID. See the following example (for the plugin Dummy with UID \"dummy\"). Each\nplugin also gets an automatic UID on the moment when rendered. In the example\nbelow it's the \"p6d06f17d-e142-4f45-b9c1-893c38fc2b01\".\n\n.. code-block:: html\n\n
\n\nLayout, placeholder, plugin and plugin widget have properties for getting their\nHTML specific classes and IDs.\n\nLayout (instance)\n\n.. code-block:: python\n\n layout.html_class\n\nPlaceholder (instance)\n\n.. code-block:: python\n\n placeholder.html_id\n placeholder.html_class\n\nPlugin (instance)\n\n.. code-block:: python\n\n plugin.html_id\n plugin.html_class\n\nPlugin widget (static call)\n\n.. code-block:: python\n\n plugin_widget.html_class # Static one\n\nCreating a new plugin\n=====================\nDash comes with several bundled plugins. Do check their source code as example.\n\nMaking of a plugin or a plugin widget is quite simple, although there are some\nrules/guidelines you should follow.\n\nLet's assume that plugin is named ``sample_memo``. The plugin directory should\nthen have the following structure.\n\nNote, that you are advised to prefix all your plugin specific media files\nwith ``dash_plugin_`` for the sake of common sense.\n\n.. code-block:: text\n\n path/to/plugin/sample_memo/\n \u251c\u2500\u2500 static\n \u2502\u00a0\u00a0 \u251c\u2500\u2500 css\n \u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u2514\u2500\u2500 dash_plugin_sample_memo.css # Plugin specific CSS\n \u2502\u00a0\u00a0 \u251c\u2500\u2500 images\n \u2502\u00a0\u00a0 \u2514\u2500\u2500 js\n \u2502\u00a0\u00a0 \u2514\u2500\u2500 dash_plugin_sample_memo.js # Plugin specific JavaScripts\n \u251c\u2500\u2500 templates\n \u2502 \u2514\u2500\u2500 sample_memo\n \u2502 \u251c\u2500\u2500 render_main.html # Plugin widget template for ``main`` Placeholder\n \u2502 \u2514\u2500\u2500 render_short.html # Plugin widget template for ``shortcuts`` Placeholder\n \u251c\u2500\u2500 __init__.py\n \u251c\u2500\u2500 dash_plugins.py # Where plugins and widgets are defined and registered\n \u251c\u2500\u2500 dash_widgets.py # Where the plugin widgets are defined\n \u2514\u2500\u2500 forms.py # Plugin configuration form\n\nIn some cases, you would need plugin specific overridable settings (see\n``dash.contrib.plugins.weather`` plugin as an example. You are advised to\nwrite your settings in such a way, that variables of your Django projects'\n``settings.py`` module would have ``DASH_PLUGIN_`` prefix.\n\npath/to/plugin/sample_memo/dash_plugins.py\n------------------------------------------\nStep by step review of a how to create and register a plugin and plugin\nwidgets. Note, that Dash auto-discovers your plugins if you place them into a\nfile named ``dash_plugins.py`` of any Django app listed in ``INSTALLED_APPS``\nof your Django projects' settings module.\n\nDefine and register the plugin\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nAs already stated, a single plugin widget is registered for a triple (layout,\nplaceholder, plugin). That means, that if you need two widgets, one sized 1x1\nand another sized 2x2, you need two plugins for it. You can either manually\ndefine all plugins and widgets for the sizes desired, or define a single\nbase plugin or a widget class and have it factory registered for a number of\ngiven sizes. Below, both approaches would be explained.\n\nRequired imports.\n\n.. code-block:: python\n\n from dash.base import BaseDashboardPlugin, plugin_registry\n from path.to.plugin.sample_memo.forms import SampleMemoForm\n\nDefining the Sample Memo plugin (2x2) (to be used in the ``main`` placeholder).\n\n.. code-block:: python\n\n class SampleMemo2x2Plugin(BaseDashboardPlugin):\n\n uid = 'sample_memo_2x2' # Plugin UID\n name = _(\"Memo\") # Plugin name\n group = _(\"Memo\") # Group to which the plugin belongs to\n form = SampleMemoForm # Plugin forms are explained later\n html_classes = ['sample-memo'] # Optional. Adds extra HTML classes.\n\nRegistering the Sample Memo plugin.\n\n.. code-block:: python\n\n plugin_registry.register(SampleMemo2x2Plugin)\n\nDefining the Sample Memo plugin (1x1) (to be used in the ``shortcuts``\nplaceholder).\n\n.. code-block:: python\n\n class SampleMemo1x1Plugin(SampleMemo2x2Plugin):\n\n uid = 'sample_memo_1x1' # Plugin UID\n\nRegistering the Sample Memo plugin.\n\n.. code-block:: python\n\n plugin_registry.register(SampleMemo1x1Plugin)\n\nRepeat the steps below for each plugin size (or read about factory registering\nthe plugins and widgets below).\n\nFactory register plugins\n~~~~~~~~~~~~~~~~~~~~~~~~\nAlternatively, you can define just a single plugin base class and have it\nfactory registered for the given sizes. The code below would produce and\nregister classes for in sizes 1x1 and 2x2. When you need to register a plugin\nfor 10 sizes, this approach clearly wins. Besides, it's very easy to get a\nclear overview of all plugins sizes registered.\n\nRequired imports.\n\n.. code-block:: python\n\n from dash.base import BaseDashboardPlugin\n from dash.factory import plugin_factory\n from path.to.plugin.sample_memo.forms import SampleMemoForm\n\nDefining the base plugin class.\n\n.. code-block:: python\n\n class BaseSampleMemoPlugin(BaseDashboardPlugin):\n\n name = _(\"Memo\") # Plugin name\n group = _(\"Memo\") # Group to which the plugin belongs to\n form = SampleMemoForm # Plugin forms are explained later\n html_classes = ['sample-memo'] # Optional. Adds extra HTML classes.\n\nNote, that we don't provide ``uid`` property in the base class.\n\nNow, that we have the base plugin defined, factory register it for the sizes\ngiven.\n\n.. code-block:: python\n\n sizes = (\n (1, 1),\n (2, 2),\n )\n plugin_factory(BaseSampleMemoPlugin, 'sample_memo', sizes)\n\nIn the example above, \"sample_memo\" is the base name of the plugin. Size\ninformation would be appended to it (\"sample_memo_1x1\", \"sample_memo_2x2\").\n\nRegister plugin widgets\n~~~~~~~~~~~~~~~~~~~~~~~\nPlugin widgets are defined in ``dash_widgets.py`` module (described later), but\nregistered in the ``dash_plugins.py``, which is auto-discovered by Dash.\n\nRequired imports.\n\n.. code-block:: python\n\n from dash.base import plugin_widget_registry\n from path.to.plugin.sample_memo.dash_widgets import (\n SampleMemo1x1ExampleMainWidget,\n SampleMemo2x2ExampleMainWidget\n )\n\nRegistering the Sample Memo plugin widget for placeholder ``main`` of layout\n`example``.\n\n.. code-block:: python\n\n plugin_widget_registry.register(SampleMemo2x2ExampleMainWidget)\n\nRegistering the Sample Memo plugin widget for placeholder ``shortcuts`` of\nlayout ``example``.\n\n.. code-block:: python\n\n plugin_widget_registry.register(SampleMemo1x1ExampleMainWidget)\n\npath/to/plugin/sample_memo/dash_widgets.py\n------------------------------------------\nWhy to have another file for defining widgets? Just to keep the code clean and\nless messy, although you could perfectly define all your plugin widgets in the\nmodule ``dash_plugins.py``, it's recommended to keep it separate.\n\nTake into consideration, that ``dash_widgets.py`` is not an auto-discovered\nfile pattern. All your plugin widgets should be registered in modules named\n``dash_plugins.py``.\n\nDefine and register the plugin widget\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nRequired imports.\n\n.. code-block:: python\n\n from django.template.loader import render_to_string\n from dash.base import BaseDashboardPluginWidget\n\nMemo plugin widget for Example layout (placeholder ``main``).\n\n.. code-block:: python\n\n class SampleMemo2x2ExampleMainWidget(BaseDashboardPluginWidget):\n\n layout_uid = 'example' # Layout for which the widget is written\n placeholder_uid = 'main' # Placeholder within the layout for which\n # the widget is written\n plugin_uid = 'sample_memo_2x2' # Plugin for which the widget is\n # written\n cols = 2 # Number of widget columns\n rows = 2 # Number of widget rows\n\n def render(self, request=None):\n context = {'plugin': self.plugin}\n return render_to_string('sample_memo/render_main.html', context)\n\nMemo plugin widget for Example layout (placeholder `shortcuts`).\n\n.. code-block:: python\n\n class SampleMemo1x1ExampleShortcutWidget(SampleMemo2x2ExampleMainWidget):\n\n placeholder_uid = 'shortcuts' # Placeholder within the layout for\n # which the widget is written\n cols = 1 # Number of widget columns\n rows = 1 # Number of widget rows\n\n def render(self, request=None):\n context = {'plugin': self.plugin}\n return render_to_string(\n 'sample_memo/render_shortcuts.html', context\n )\n\nFactory register plugin widgets\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nAlternatively, you can define just a single plugin widget base class and have\nit factory registered for the given sizes. The code below would produce and\nregister classes for in sizes 1x1 and 2x2.\n\nRequired imports.\n\n.. code-block:: python\n\n from django.template.loader import render_to_string\n from dash.factory import plugin_widget_factory\n from dash.base import BaseDashboardPluginWidget\n\nDefining the base plugin widget class.\n\n.. code-block:: python\n\n class BaseSampleMemoWidget(BaseDashboardPluginWidget):\n\n def render(self, request=None):\n context = {'plugin': self.plugin}\n return render_to_string('sample_memo/render.html', context)\n\nNow, that we have the base plugin defined, factory register it for the sizes\ngiven.\n\n.. code-block:: python\n\n sizes = (\n (1, 1),\n (2, 2),\n )\n plugin_widget_factory(\n BaseSampleMemoWidget, 'example', 'main', 'sample_memo', sizes\n )\n\nIn the example above:\n\n- \"sample_memo\" is the base name of the plugin and it should match the name\n given to plugin factory exactly.\n- \"example\" is the uid of the layout, for which the widget is being registered.\n- \"main\" is the uid of the placeholder, for which the widget it being\n registered.\n\npath/to/plugin/sample_memo/forms.py\n-----------------------------------\nWhat are the plugin forms? Very simple - if plugin is configurable, it has a\nform. If you need to have a custom CSS or a JavaScript included when rendering\na specific form, use Django's class Media directive in the form.\n\nRequired imports.\n\n.. code-block:: python\n\n from django import forms\n from dash.base import DashboardPluginFormBase\n\nMemo form (for `Sample Memo` plugin).\n\n.. code-block:: python\n\n class SampleMemoForm(forms.Form, DashboardPluginFormBase):\n\n plugin_data_fields = [\n (\"title\", \"\"),\n (\"text\", \"\")\n ]\n\n title = forms.CharField(label=_(\"Title\"), required=False)\n text = forms.CharField(label=_(\"Text\"), required=True,\n widget=forms.widgets.Textarea)\n\n def __init__(self, *args, **kwargs):\n super(MemoForm, self).__init__(*args, **kwargs)\n\nNow, that everything is ready, make sure your that both layout and the plugin\nmodules are added to ``INSTALLED_APPS`` for your projects' Django ``settings.py``\nmodule.\n\n.. code-block:: python\n\n INSTALLED_APPS = (\n # ...\n 'path.to.layout.example',\n 'path.to.plugin.sample_memo',\n # ...\n )\n\nAfter it's done, go to terminal and type the following command.\n\n.. code-block:: sh\n\n ./manage.py dash_sync_plugins\n\nIf your HTTP server is running, you would then be able to access your dashboard.\n\n- View URL: http://127.0.0.1:8000/dashboard/\n- Edit URL: http://127.0.0.1:8000/dashboard/edit/\n\nNote, that you have to be logged in, in order to use the dashboard. If your new\nplugin doesn't appear, set the ``DASH_DEBUG`` to True in your Django's local\nsettings module (`local_settings.py`), re-run your code and check console for\nerror notifications.\n\nPlugin and widget factory\n=========================\nIn general, when making a new plugin, base widgets are made for then too. By\ncreating base widgets you avoid duplication of the code. See the example below.\n\n.. code-block:: python\n\n from dash.base import BaseDashboardPlugin\n\n class BaseMemoPlugin(BaseDashboardPlugin):\n\n name = _(\"Memo\")\n group = _(\"Memo\")\n form = MemoForm\n\nNow that we have the base plugin, we can use plugin factory to generate and\nregister plugin classes of the required dimensions.\n\n.. code-block:: python\n\n from dash.factory import plugin_factory\n plugin_factory(BaseMemoPlugin, 'memo', ((5, 6), (6, 5), (6, 6)))\n\nThe code above will generate \"memo_5x6\", \"memo_6x5\" and \"memo_6x6\" plugin\nclasses which subclass the ``BaseMemoPlugin`` and register them in the plugin\nregistry. The ``uid`` property would be automatically generated.\n\nSame goes for the widgets.\n\n.. code-block:: python\n\n from dash.base import BaseDashboardPluginWidget\n\n class BaseMemoWidget(BaseDashboardPluginWidget):\n\n def render(self, request=None):\n context = {'plugin': self.plugin}\n return render_to_string('memo/render.html', context)\n\nNow that we have the base widget, we can use plugin widget factory to generate\nand register plugin widget classes of the required dimensions.\n\n.. code-block:: python\n\n from dash.factory import plugin_widget_factory\n\n plugin_widget_factory(\n BaseMemoWidget,\n 'bootstrap2_fluid',\n 'main',\n 'memo',\n ((5, 6), (6, 5), (6, 6))\n )\n\nThe code above will generate \"memo_5x6\", \"memo_6x5\" and \"memo_6x6\" plugin\nwidget classes which subclass the ``BaseMemoWidget`` and register them in the\nplugin widget registry. The ``layout_uid``, ``placeholder_uid``,\n``plugin_uid``, ``cols`` and ``rows`` properties would be automatically\ngenerated.\n\nOf course, there would be cases when you can't use factory, for example because\neach of your plugins or widgets differs from others by tiny important bits, but\nif you notice yourself subclassing the base widget or plugin many times without\nany change to the code, then it's perhaps a right time to start using the\nfactory.\n\nLayout, plugin and widget summary\n=================================\nWhen making your own layouts, plugins and plugin widgets you are free to use\nthe API as you wish. While developing the Dash, I found the follow practices\nuseful:\n\n- When making a new plugin, always make a base plugin class, from which all \n size specific ones would derive.\n- Do create base plugin widgets (with HTML templates) in the plugin, but do not \n register them there. Use factory (``dash.factory``) to generate and register\n layout specific plugin widgets - preferably in the layout module.\n- If you're adding custom plugin to existing bundled layout (those that \n reside in ``dash.contrib.layouts``), create a new module named\n ``dash_custom`` (or any other name that you prefer) and factory\n generate/register your layout specific plugin widgets in a module named\n ``dash_plugins.py`` (do not forget to add the module to ``INSTALLED_APPS``,\n so that it auto-discovered).\n\nPermissions\n===========\nPlugin system allows administrators to specify the access rights to every \nplugin. Dash permissions are based on Django Users and User Groups. Access\nrights are manageable via Django admin (/administration/dash/dashboardplugin/).\nNote, that your admin URL prefix may vary from the one given in example (it's\nusually \"/admin/\", while in example it's \"/administration/\"). If user doesn't\nhave the rights to access plugin, it doesn't appear on his dashboard even if\nhas been added to it (imagine, you have once granted the right to use the news\nplugin to all users, but later on decided to limit it to Staff members group\nonly). Note, that superusers have access to all plugins.\n\n.. code-block:: text\n\n Plugin access rights management interface in Django admin\n \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n \u2502 `Plugin` \u2502 `Users` \u2502 `Groups` \u2502\n \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502 Video (big_video) \u2502 John Doe \u2502 Dashboard users \u2502\n \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502 TinyMCE memo (tinymce_memo) \u2502 \u2502 Dashboard users \u2502\n \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502 News (news) \u2502 Oscar, John Doe \u2502 Staff members \u2502\n \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502 URL (url) \u2502 \u2502 Dashboard users \u2502\n \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502 Video (video) \u2502 \u2502 Dashboard users \u2502\n \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502 Dummy (dummy) \u2502 \u2502 Testers \u2502\n \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502 Dummy (large_dummy) \u2502 \u2502 Testers \u2502\n \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502 Memo (big_memo) \u2502 \u2502 Dashboard users \u2502\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\nManagement commands\n===================\nThere are several management commands.\n\n- ``dash_find_broken_dashboard_entries``. Find broken dashboard entries that\n occur when some plugin which did exist in the system, no longer exists.\n- ``dash_sync_plugins``. Should be ran each time a new plugin is being added\n to the Dash.\n- ``dash_update_plugin_data``. A mechanism to update existing plugin data in\n case if it had become invalid after a change in a plugin. In order for it\n to work, each plugin should implement and ``update`` method, in which the\n data update happens.\n\nTuning\n======\nThere are number of Dash settings you can override in the `settings.py` module\nof your Django project:\n\n- ``DASH_RESTRICT_PLUGIN_ACCESS`` (bool): If set to True, (Django) permission\n system for dash plugins is enabled. Defaults to True. Setting this to False\n makes all plugins available for all users.\n- ``DASH_ACTIVE_LAYOUT`` (str): Active (default) layout UID. Defaults to\n \"android\".\n- ``DASH_LAYOUT_CELL_UNITS`` (str): Allowed values for layout cell units.\n Defaults to (\"em\", \"px\", \"pt\", \"%\").\n- ``DASH_DISPLAY_AUTH_LINK`` (bool): If set to True, the log out link is shown\n in the Dash drop-down menu. Defaults to True.\n\nFor tuning of specific contrib plugin, see the docs in the plugin directory.\n\nStyling tips\n============\nFont Awesome is used for icons. As a convention, all icons of font-awesome are\nplaced within a span. Next to their original class, they all should be getting\nan extra class \"iconic\". Follow that rule when making a new layout or a\nplugin (HTML). It allows to make the styling easy, since icon colours could be\nthen changed within no time.\n\nBundled plugins and layouts\n===========================\nDash ships with number of bundled (demo) plugins and layouts that are mainly\nmade to demonstrate its' abilities. In order to work among various layouts\n(themes), each plugin has a single widget registered for a single layout.\nIt's possible to unregister a bundled widget and replace it with a custom one.\n\nBundled plugins\n---------------\nBelow a short overview of the plugins. See the README.rst file in directory\nof each plugin for details.\n\n- `Dummy plugin\n `_.\n Mainly made for quick testing. Still, is perfect example of how to write a\n plugin and widgets.\n- `Image plugin\n `_.\n Allows users to put images on their dashboard. If you plan to make a plugin\n that deals with file uploads, make sure to check the source of this one\n first.\n- `Memo plugin\n `_.\n Allows users to put short notes on their dashboard.\n- `RSS feed plugin\n `_.\n Allows users to put any RSS feed right into the dashboard.\n- `URL plugin\n `_.\n Allows users to put links to their dashboard.\n- `Bookmark plugin\n `_.\n Allows users to put bookmarks to their dashboard. Bookmarks are added by\n the administrator.\n- `Video plugin\n `_.\n Allows users to put YouTube or Vimeo videos to their dashboard.\n- `Weather plugin\n `_.\n Allows to put a weather widget into dashboard.\n\nDemo plugins\n------------\n- `Sample D3 plugins\n `_.\n Shows how to transform D3.js charts into Dash plugins.\n- `Sample Polychart2 plugin\n `_.\n Shows how to transform Polychart2.js charts into Dash plugins.\n- `News plugin\n `_.\n Shows how to embed your Django news application (front-end part of it) into\n a Dash plugin widget.\n\nBundled layouts\n---------------\nBelow a short overview of the layouts. See the README.rst file in directory\nof each layout for details.\n\n- `Android \n `_\n (like) layout. Has two placeholders: main (6 cols x 5 rows, each block sized\n 150x110 px) and shortcuts (1 col x 10 rows, each block sized 60x55 px).\n- `Bootstrap 2 fluid \n `_\n (like) layout. Has one placeholder: main (11 cols x 9 rows, each block sized\n 70x40 px).\n- `Windows 8 \n `_\n (like) layout. Has two placeholders: main (6 cols x 4 rows, each block sized\n 140x135 px) and sidebar (2 cols x 4 rows, each block sized 140x135 px).\n\nDemo layouts\n------------\n- `Example\n `_\n layout. Has five placeholders: top (8 cols x 1 rows, each block sized\n 55x55 px), right (3 col x 8 rows, each block sized 55x55 px), bottom (\n 8 cols x 1 rows, each block sized 55x55 px), left (3 col x 8 rows, each\n block sized 55x55 px) and main (5 col x 4 rows, each block sized 110x95 px).\n\nNaming conventions\n==================\nAlthough you are free to name your plugins and widgets as you want (except that\nyou should comply with `PEP-008\n`_), there are some\nnaming conventions introduced, that you are recommended to follow.\n\n- Example1x1Plugin: 1x1 example plugin\n - Example1x1AndroidMainWidget: 1x1 widget for 1x1 example plugin (layout\n Android, placeholder 'main')\n - Example1x1AndroidShortcutsWidget: 1x1 widget for 1x1 example plugin (\n layout Android, placeholder 'shortcuts')\n - Example1x1Windows8MainWidget: 1x1 widget for 1x1 example plugin (layout\n Windows 8, placeholder 'main')\n - Example1x1Windows8SidebarWidget: 1x1 widget for 1x1 example plugin (\n layout Windows 8, placeholder 'sidebar')\n\n- Example2x3Plugin: 2x3 example plugin\n - Example2x3Windows8MainWidget: 2x3 widget for 2x3 example plugin (layout\n Windows 8, placeholder 'main')\n - Example2x3Windows8SidebarWidget: 2x3 widget for 2x3 example plugin (\n layout Windows 8, placeholder 'sidebar')\n\n- Example6x1Plugin: 6x1 example plugin\n - Example6x1YourLayoutSidebarWidget: 6x1 widget for 6x1 example plugin (\n layout Your Layout, placeholder 'main')\n\nDebugging\n=========\nMost of the errors are logged (DEBUG). If you have written a plugin and it\nsomehow doesn't appear in the list of available plugins, do run the following\nmanagement command:\n\n.. code-block:: sh\n\n ./manage.py dash_sync_plugins\n\nThe ``dash_sync_plugins`` not only syncs your plugins into the database, but\nalso is a great way of checking for possible errors.\n\nAvailable translations\n======================\n- Dutch (core and plugins)\n- Russian (core and plugins)\n\nTroubleshooting\n===============\n- If you somehow get problems installing ``Dash``, check the `example\n `__\n project and the `requirements.txt\n `__.\n\nTesting\n=======\nProject is covered by test (functional- and browser-tests).\n\nPy.test is used as a default test runner.\n\nTo test with all supported Python/Django versions type:\n\n.. code-block:: sh\n\n tox\n\nTo test against specific environment, type:\n\n.. code-block:: sh\n\n tox -e py35-django18\n\nTo test just your working environment type:\n\n.. code-block:: sh\n\n ./runtests.py\n\nTo tests just your working environment (with Django test runner) type:\n\n.. code-block:: sh\n\n ./manage.py test dash\n\nIt's assumed that you have all the requirements installed. If not, first\ninstall the test requirements:\n\n.. code-block:: sh\n\n pip install -r examples/requirements/test.txt\n\nBrowser tests\n-------------\nFor browser tests you may choose between Firefox, headless Firefox and\nPhantomJS. PhantomJS is faster, headless Firefox is fast as well, but\nnormal Firefox tests tell you more (as you see what exactly happens on the\nscreen). Both cases require some effort and both have disadvantages regarding\nthe installation (although once you have them installed they work perfect).\n\nLatest versions of Firefox are often not supported by Selenium. Current\nversion of the Selenium for Python (2.53.6) works fine with Firefox 47.\nThus, instead of using system Firefox you could better use a custom one.\n\nFor PhantomJS you need to have NodeJS installed.\n\nSet up Firefox 47\n~~~~~~~~~~~~~~~~~\n1. Download Firefox 47 from\n `this\n `__\n location and unzip it into ``/usr/lib/firefox47/``\n\n2. Specify the full path to your Firefox in ``FIREFOX_BIN_PATH``\n setting. Example:\n\n .. code-block:: python\n\n FIREFOX_BIN_PATH = '/usr/lib/firefox47/firefox'\n\n If you set ``FIREFOX_BIN_PATH`` to None, system Firefox would be used.\n\nAfter that your Selenium tests would work.\n\nSet up headless Firefox\n~~~~~~~~~~~~~~~~~~~~~~~\n1. Install ``xvfb`` package which is used to start Firefox in headless mode.\n\n .. code-block:: sh\n\n sudo apt-get install xvfb\n\n2. Run the tests using headless Firefox.\n\n .. code-block:: sh\n\n ./scripts/runtests.sh\n\n Or run tox tests using headless Firefox.\n\n .. code-block:: sh\n\n ./scripts/tox.sh\n\nSetup PhantomJS\n~~~~~~~~~~~~~~~\nYou could also run tests in headless mode (faster). For that you will need\nPhantomJS.\n\n1. Install PhantomJS and dependencies.\n\n .. code-block:: sh\n\n curl -sL https://deb.nodesource.com/setup_6.x -o nodesource_setup.sh\n sudo bash nodesource_setup.sh\n sudo apt-get install nodejs\n sudo apt-get install build-essential libssl-dev\n sudo npm -g install phantomjs-prebuilt\n\n2. Specify the ``PHANTOM_JS_EXECUTABLE_PATH`` setting. Example:\n\n .. code-block:: python\n\n PHANTOM_JS_EXECUTABLE_PATH = \"\"\n\n If you want to use Firefox for testing, set\n ``PHANTOM_JS_EXECUTABLE_PATH`` to None.\n\nLicense\n=======\nGPL 2.0/LGPL 2.1\n\nSupport\n=======\nFor any issues contact me at the e-mail given in the `Author`_ section.\n\nAuthor\n======\nArtur Barseghyan \n\nScreenshots\n===============================================\nAndroid layout\n-----------------------------------------------\nSeveral screenshots of Android layout are presented below.\n\nDashboard workspace (view mode) on which you can see the following plugins used:\n\n - URL plugin\n - TinyMCE Memo plugin\n - Memo plugin\n - Video plugin\n\n.. figure:: https://github.com/barseghyanartur/django-dash/raw/master/docs/_static/dash/dashboard_view_1.png\n :align: center\n\nDashboard workspace (edit mode), which is a edit mode of the above mentioned dashboard workspace.\n\n.. figure:: https://github.com/barseghyanartur/django-dash/raw/master/docs/_static/dash/dashboard_edit_full_1.png\n :align: center\n\nDashboard workspace (view mode) on which you can see the following plugins used:\n\n - News plugin\n - RSS feed plugin\n - Dummy plugin\n - URL plugin\n\n.. figure:: https://github.com/barseghyanartur/django-dash/raw/master/docs/_static/dash/dashboard_view_2.png\n :align: center\n :width: 900px\n\nDashboard workspace (edit mode), which is a edit mode of the above mentioned dashboard workspace.\n\n.. figure:: https://github.com/barseghyanartur/django-dash/raw/master/docs/_static/dash/dashboard_edit_full_2.png\n :align: center\n :width: 900px\n\nDashboard workspace (edit mode) is an empty dashboard workspace in edit mode.\n\n.. figure:: https://github.com/barseghyanartur/django-dash/raw/master/docs/_static/dash/dashboard_edit_empty_1.png\n :align: center\n :width: 900px\n\nChoose widget to added to the dashboard workspace.\n\n.. figure:: https://github.com/barseghyanartur/django-dash/raw/master/docs/_static/dash/dashboard_edit_empty_add_widget_1.png\n :align: center\n :width: 900px\n\nTinyMCE plugin widget form\n\n.. figure:: https://github.com/barseghyanartur/django-dash/raw/master/docs/_static/dash/dash_plugin_tinymce_memo_add_1.png\n :align: center\n\nDashboard workspace (edit mode) on which the TinyMCE plugin widget has been just added. Menu is unfolded.\n\n.. figure:: https://github.com/barseghyanartur/django-dash/raw/master/docs/_static/dash/dashboard_edit_progress_with_menu_1.png\n :align: center\n :width: 900px\n\nA form to edit global dashboard settings.\n\n.. figure:: https://github.com/barseghyanartur/django-dash/raw/master/docs/_static/dash/dashboard_edit_settings_1.png\n :align: center\n :width: 900px\n\nA form to edit settings of current dashboard workspace.\n\n.. figure:: https://github.com/barseghyanartur/django-dash/raw/master/docs/_static/dash/dashboard_edit_workspace_1.png\n :align: center\n :width: 900px\n\nBootstrap 2 Fluid layout\n-----------------------------------------------\nSeveral screenshots of Bootstrap 2 Fluid layout are presented below.\n\nDashboard workspace (edit mode) is an empty dashboard workspace in edit mode.\n\n.. figure:: https://github.com/barseghyanartur/django-dash/raw/master/docs/_static/dash/bootstrap2_edit_dashboard_empty_2.png\n :align: center\n :width: 900px\n\nDashboard workspace (edit mode) - a dashboard workspace filled.\n\n.. figure:: https://github.com/barseghyanartur/django-dash/raw/master/docs/_static/dash/bootstrap2_edit_dashboard_1.png\n :align: center\n :width: 900px\n\nDashboard workspace (view mode) of the above mentioned dashboard workspace.\n\n.. figure:: https://github.com/barseghyanartur/django-dash/raw/master/docs/_static/dash/bootstrap2_view_dashboad_1.png\n :align: center\n :width: 900px\n\nPublic dashboard of above mentioned dashboard workspace.\n\n.. figure:: https://github.com/barseghyanartur/django-dash/raw/master/docs/_static/dash/bootstrap2_public_dashboard_1.png\n :align: center\n :width: 900px\n\nEdit dashboard settings dialogue.\n\n.. figure:: https://github.com/barseghyanartur/django-dash/raw/master/docs/_static/dash/bootstrap2_edit_settings_1.png\n :align: center\n :width: 900px\n\nBubble Chart, Stacked-to-Grouped Bars and Sunburst Partition (view dashboard\nmode).\n\n.. figure:: https://github.com/barseghyanartur/django-dash/raw/master/docs/_static/dash/d3_sample_charts_view_dashboard.png\n :align: center\n :width: 900px\n\nBubble Chart, Stacked-to-Grouped Bars and Sunburst Partition (edit dashboard\nmode).\n\n.. figure:: https://github.com/barseghyanartur/django-dash/raw/master/docs/_static/dash/d3_sample_charts_edit_dashboard.png\n :align: center\n :width: 900px\n\nExample layout\n-----------------------------------------------\nSeveral screenshots of Example layout are presented below.\n\nDashboard workspace (edit mode) is an empty dashboard workspace in edit mode.\n\n.. figure:: https://github.com/barseghyanartur/django-dash/raw/master/docs/_static/dash/dashboard_edit_empty_2_example_layout.png\n :align: center\n :width: 900px\n\nDashboard workspace (edit mode) - above mentioned dashboard workspace was filled with images.\n\n.. figure:: https://github.com/barseghyanartur/django-dash/raw/master/docs/_static/dash/dashboard_edit_full_3_example_layout.png\n :align: center\n :width: 900px\n\nDashboard workspace (view mode) of the above mentioned dashboard workspace\n\n.. figure:: https://github.com/barseghyanartur/django-dash/raw/master/docs/_static/dash/dashboard_view_3_example_layout.png\n :align: center\n :width: 900px\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/barseghyanartur/django-dash/", "keywords": "dashboard", "license": "GPL 2.0/LGPL 2.1", "maintainer": "", "maintainer_email": "", "name": "django-dash", "package_url": "https://pypi.org/project/django-dash/", "platform": "", "project_url": "https://pypi.org/project/django-dash/", "project_urls": { "Homepage": "https://github.com/barseghyanartur/django-dash/" }, "release_url": "https://pypi.org/project/django-dash/0.5.6/", "requires_dist": null, "requires_python": "", "summary": "Customisable, modular dashboard application framework for Django.", "version": "0.5.6" }, "last_serial": 5641736, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "2ce42a8989f233279843d98c4b376bc4", "sha256": "b7286c4ea98d8be731a85ee83f6e5d8e035e4b6ceae6fc9cd716ef45244eca7a" }, "downloads": -1, "filename": "django-dash-0.1.tar.gz", "has_sig": false, "md5_digest": "2ce42a8989f233279843d98c4b376bc4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1906805, "upload_time": "2013-10-30T02:04:11", "url": "https://files.pythonhosted.org/packages/34/91/1f87f97ab5d1be31ec10295a57450a13751e53b62bc9ba06a0c41ff7e364/django-dash-0.1.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "34aa34984ba4a2d6434be2c915eb7c1e", "sha256": "cb60f5f214d4bdf6cabd987cd87c1002721a6cc98f3a899d9b6efc556d314c99" }, "downloads": -1, "filename": "django-dash-0.1.1.tar.gz", "has_sig": false, "md5_digest": "34aa34984ba4a2d6434be2c915eb7c1e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1908088, "upload_time": "2013-10-31T00:07:28", "url": "https://files.pythonhosted.org/packages/e4/d1/8b7f6e07df4095fbd11435a2e485de065929baf62e4e7c4cac9639598879/django-dash-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "1d34ca40f7a22c277461c76d8b55c725", "sha256": "2cb552045ab6001b2725bac123c32e8dcbe72218aaf483556fcd14e6b372e99a" }, "downloads": -1, "filename": "django-dash-0.1.2.tar.gz", "has_sig": false, "md5_digest": "1d34ca40f7a22c277461c76d8b55c725", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1910073, "upload_time": "2013-10-31T22:20:38", "url": "https://files.pythonhosted.org/packages/e1/d9/6ff54287d217e86fa0e3d94bffd2b222888de400a5a8a14c07f68359c28d/django-dash-0.1.2.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "bbfc13fd1a17290d0f26ef0fbf482241", "sha256": "9dfe26d0fef073f6262610114227020d1c322af1de9fada47e5823c96748815c" }, "downloads": -1, "filename": "django-dash-0.1.3.tar.gz", "has_sig": false, "md5_digest": "bbfc13fd1a17290d0f26ef0fbf482241", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1917462, "upload_time": "2013-11-01T22:12:32", "url": "https://files.pythonhosted.org/packages/3d/7f/4547fb59c6313b1fa9a553cb9d56960c17591e3744feceec8a14248a70c0/django-dash-0.1.3.tar.gz" } ], "0.1.4": [ { "comment_text": "", "digests": { "md5": "17fb8b7c0974bcf435ac4c29a1cb77d9", "sha256": "b3fc9b2d625481d5fcda3ff05c205fb73f50864d16866b9f9ff24355bfab5241" }, "downloads": -1, "filename": "django-dash-0.1.4.tar.gz", "has_sig": false, "md5_digest": "17fb8b7c0974bcf435ac4c29a1cb77d9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1926404, "upload_time": "2013-11-05T21:01:11", "url": "https://files.pythonhosted.org/packages/7e/2c/c9adad6471178a9ecede4a88f81b7147a1630c034b1414d3c637b339fc9a/django-dash-0.1.4.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "fd36449171033b8c7b56081dc8fdbd71", "sha256": "6c913df61659f1108e0241e9459f5da62a877282867191cd6dfca7aef86de99d" }, "downloads": -1, "filename": "django-dash-0.2.tar.gz", "has_sig": false, "md5_digest": "fd36449171033b8c7b56081dc8fdbd71", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1943373, "upload_time": "2013-11-07T01:42:01", "url": "https://files.pythonhosted.org/packages/c2/c8/681e6ff73225cd0a4ef8acfb519a706cdac7f12c23d8503f6744d9990ab7/django-dash-0.2.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "da0928075e158cd538d4d3019d685dfc", "sha256": "611bc3051b5c4f6ea40cdf533b9ee9c7a0861945d1b6088b48ef051914ba5bc5" }, "downloads": -1, "filename": "django-dash-0.2.1.tar.gz", "has_sig": false, "md5_digest": "da0928075e158cd538d4d3019d685dfc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1944152, "upload_time": "2013-11-07T01:59:42", "url": "https://files.pythonhosted.org/packages/48/85/b3da89f0d674652dac525c3dbcfb41607667fa15649f74ffcd86e758da17/django-dash-0.2.1.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "84c80987e1ae67c1e99601a87a93cc24", "sha256": "44f778382136b7c8c521ba01565e366fd13063cb5f74f6fee23b210e09e0ed35" }, "downloads": -1, "filename": "django-dash-0.2.2.tar.gz", "has_sig": false, "md5_digest": "84c80987e1ae67c1e99601a87a93cc24", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1956263, "upload_time": "2013-11-07T21:23:45", "url": "https://files.pythonhosted.org/packages/83/2b/2f4fafe58e1bf598406b7c0c548016e49b5c58e96dad9f366a71cb14ba33/django-dash-0.2.2.tar.gz" } ], "0.2.3": [ { "comment_text": "", "digests": { "md5": "de013ddf42f5872cdff87d648e2ba08f", "sha256": "3c56391a6c6ec0a9f8b0ec2ef43a79603bc1e8a5d18d9fe8223c75498e3e05ba" }, "downloads": -1, "filename": "django-dash-0.2.3.tar.gz", "has_sig": false, "md5_digest": "de013ddf42f5872cdff87d648e2ba08f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1957653, "upload_time": "2013-11-09T03:43:07", "url": "https://files.pythonhosted.org/packages/d2/1e/a979a269de5497217684ab5008c01be78015d6fa6578b6e73c7f7c850e3e/django-dash-0.2.3.tar.gz" } ], "0.2.4": [ { "comment_text": "", "digests": { "md5": "5378452afa975cc28bf7d85c16bb31b6", "sha256": "26c445e4ceb5f920f2f08197d9078177bf51ddda1ae8cc39346baa385571f4b7" }, "downloads": -1, "filename": "django-dash-0.2.4.tar.gz", "has_sig": false, "md5_digest": "5378452afa975cc28bf7d85c16bb31b6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1958361, "upload_time": "2013-11-09T17:47:47", "url": "https://files.pythonhosted.org/packages/15/17/0f1da341601ec683e62fdcef31ce9831380437fab41464eec90d69fb94de/django-dash-0.2.4.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "8184572e7cbc89a0df6eb81b3d863669", "sha256": "9c064ddcfe7eb941f4497c76a8348c5443b83e05d03e9a677049d5e71be1a240" }, "downloads": -1, "filename": "django-dash-0.3.tar.gz", "has_sig": false, "md5_digest": "8184572e7cbc89a0df6eb81b3d863669", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2048515, "upload_time": "2013-11-24T02:36:08", "url": "https://files.pythonhosted.org/packages/04/4d/e732da814a9a6f989991b5e2e66c9e0cca9aba9deac26de591ce412f085e/django-dash-0.3.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "39d1956cc4af7d3585444c23dc26b114", "sha256": "5b02f86e07ac71dd50e66be40356d09baf236c4008dc9514c73dd5d45794b250" }, "downloads": -1, "filename": "django-dash-0.3.1.tar.gz", "has_sig": false, "md5_digest": "39d1956cc4af7d3585444c23dc26b114", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2049314, "upload_time": "2013-11-24T11:51:39", "url": "https://files.pythonhosted.org/packages/89/f6/258f22a0037b57605c7151d30acd98974d931f606ff3d22868af9d88b5d8/django-dash-0.3.1.tar.gz" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "0b4291d3302bd22866d3c1da6b3b1b85", "sha256": "675faa6b2fa638a9eab647e765d5e4998d44d317c67446867739d671874cc4ea" }, "downloads": -1, "filename": "django-dash-0.3.2.tar.gz", "has_sig": false, "md5_digest": "0b4291d3302bd22866d3c1da6b3b1b85", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2049305, "upload_time": "2013-11-24T12:14:01", "url": "https://files.pythonhosted.org/packages/fc/01/01f04c0ae3691cf5c195846e9f34c60ac98d70e1c28facbc9b9450b3af5e/django-dash-0.3.2.tar.gz" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "df5ffed517d05d0559e23d622522b7e5", "sha256": "078dc47c22497ab6f5b628d2c0e566686301a38969be75d8b510caeecf1dde08" }, "downloads": -1, "filename": "django-dash-0.4.tar.gz", "has_sig": false, "md5_digest": "df5ffed517d05d0559e23d622522b7e5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2060565, "upload_time": "2013-12-08T05:33:11", "url": "https://files.pythonhosted.org/packages/0b/c6/28283a8e6d7d0d60a2ca0471b217ed74e15caa7a276f3996fcbe37cb40b0/django-dash-0.4.tar.gz" } ], "0.4.1": [ { "comment_text": "", "digests": { "md5": "f9cf84f6bbcf4e554ee56269600243c5", "sha256": "839163e9cf0ab85474bce9e8d2d215ac89f973e4c541778aad4a7aface6a4c25" }, "downloads": -1, "filename": "django-dash-0.4.1.tar.gz", "has_sig": false, "md5_digest": "f9cf84f6bbcf4e554ee56269600243c5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2065662, "upload_time": "2013-12-08T10:25:52", "url": "https://files.pythonhosted.org/packages/e1/d8/a191888bc96f28d64b7513a9b3f88d067f0d686865749a44b14f42dfa27e/django-dash-0.4.1.tar.gz" } ], "0.4.10": [ { "comment_text": "", "digests": { "md5": "3b55e96ce5925a8f3eb6d12cf6a30ccf", "sha256": "f1c112cad6c5ac0b2a2aabe34865043932b4a39d75989268a040f118b749b8a1" }, "downloads": -1, "filename": "django-dash-0.4.10.tar.gz", "has_sig": false, "md5_digest": "3b55e96ce5925a8f3eb6d12cf6a30ccf", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2069279, "upload_time": "2014-12-10T13:31:13", "url": "https://files.pythonhosted.org/packages/df/41/e9ac0730ed0043ecbfd578c77d3007ac49e33b9dec934d91ab52ef33dab6/django-dash-0.4.10.tar.gz" } ], "0.4.11": [ { "comment_text": "", "digests": { "md5": "5effdb764250b2d712e59f7aac33fcf0", "sha256": "c049306340f915eedeb9b9ce03e4741ca0c2c785d74fc551707be7975fe6aa3e" }, "downloads": -1, "filename": "django-dash-0.4.11.tar.gz", "has_sig": false, "md5_digest": "5effdb764250b2d712e59f7aac33fcf0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2072077, "upload_time": "2014-12-21T03:08:17", "url": "https://files.pythonhosted.org/packages/26/cc/8f7d89359b57c4929d1d9c3474e2585ccd031c85277f86821a64ed4c457c/django-dash-0.4.11.tar.gz" } ], "0.4.12": [ { "comment_text": "", "digests": { "md5": "636b0a1bf66674403c90cc56356bb024", "sha256": "84f119d46a87de82dcaffebe4fff0d5ca167509838f474dcd93c0469220cb4b6" }, "downloads": -1, "filename": "django_dash-0.4.12-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "636b0a1bf66674403c90cc56356bb024", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 2523091, "upload_time": "2015-01-08T23:33:42", "url": "https://files.pythonhosted.org/packages/f7/d7/4cffb32d3324f652150a1703ff9c71294b6177a4ed2d5581394859de7ff0/django_dash-0.4.12-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0335f8a6fd01e496c8d4b72057e29358", "sha256": "1b93b2fb326499a4a7c14f94869299d2d8a5db9e78f3f8975f697f6b2d6c901a" }, "downloads": -1, "filename": "django-dash-0.4.12.tar.gz", "has_sig": false, "md5_digest": "0335f8a6fd01e496c8d4b72057e29358", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2075324, "upload_time": "2015-01-08T22:53:46", "url": "https://files.pythonhosted.org/packages/07/ea/98410454015957aa2bf78b2159bb2e7770e60e3b99b397f5c774e6282dc6/django-dash-0.4.12.tar.gz" } ], "0.4.13": [ { "comment_text": "", "digests": { "md5": "2252f63d5647867a9231e8c8b8bb148f", "sha256": "9cf4f8f6cb7e1de724a0aec1d550b341c62c7b454671c2ca18dd7ea6515b6842" }, "downloads": -1, "filename": "django_dash-0.4.13-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "2252f63d5647867a9231e8c8b8bb148f", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 2517106, "upload_time": "2015-03-20T11:49:31", "url": "https://files.pythonhosted.org/packages/d6/3c/45c29287afdd5425d3e5a0c60885eee36557fcc9cd38dcb4759e5c2ef242/django_dash-0.4.13-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b36db12641f4790e77adaa5eb0867b17", "sha256": "da4bf18873c1fccaee274f8847e54a8390686c701fb348e36786fe8f007b79eb" }, "downloads": -1, "filename": "django-dash-0.4.13.tar.gz", "has_sig": false, "md5_digest": "b36db12641f4790e77adaa5eb0867b17", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2072740, "upload_time": "2015-03-20T11:49:25", "url": "https://files.pythonhosted.org/packages/8e/4f/415f08e47ef145e467714271b1339f09317db46504abe40ff1f34eb578e2/django-dash-0.4.13.tar.gz" } ], "0.4.2": [ { "comment_text": "", "digests": { "md5": "946f44f66f825c2e76882ea217baded2", "sha256": "e8503c4d8f1c666c9086e0069a07d36c064badfc82ed5f6d270502cdb6362c24" }, "downloads": -1, "filename": "django-dash-0.4.2.tar.gz", "has_sig": false, "md5_digest": "946f44f66f825c2e76882ea217baded2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2065781, "upload_time": "2013-12-08T12:48:10", "url": "https://files.pythonhosted.org/packages/55/87/9742ea4327b1e93ace8012003587e5cab9be8121310cd32b3d4bc23cd0a3/django-dash-0.4.2.tar.gz" } ], "0.4.3": [ { "comment_text": "", "digests": { "md5": "e6195f7a2217932b022c8fbacce7da69", "sha256": "b2b99765818929d87b097ac148c60499b0e845766d1457dbc24f4ae0a95773b6" }, "downloads": -1, "filename": "django-dash-0.4.3.tar.gz", "has_sig": false, "md5_digest": "e6195f7a2217932b022c8fbacce7da69", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2069310, "upload_time": "2013-12-22T01:53:44", "url": "https://files.pythonhosted.org/packages/88/2d/b585d3d9b7b84156ce3228f06cdfc397d2032668621a6be42f380777b481/django-dash-0.4.3.tar.gz" } ], "0.4.4": [ { "comment_text": "", "digests": { "md5": "d54356ca362f302d54b63a3dc35c68d4", "sha256": "410e340f7a4d8688536fc1333b5227908224ff4a50e53f2c6b88987b9bf8b375" }, "downloads": -1, "filename": "django-dash-0.4.4.tar.gz", "has_sig": false, "md5_digest": "d54356ca362f302d54b63a3dc35c68d4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2070304, "upload_time": "2014-03-26T02:29:19", "url": "https://files.pythonhosted.org/packages/16/8e/e53cd3a9cd733089bd0a7ffb645e57ca06a7533dcd62c693d18689d0dac7/django-dash-0.4.4.tar.gz" } ], "0.4.5": [ { "comment_text": "", "digests": { "md5": "d05d98dcd3cd506d70a152ce3af0b99f", "sha256": "fa4eb3ceafd741a122db35b1ce9f3ccca6d41a4ed1befae9e15d2de46f538000" }, "downloads": -1, "filename": "django-dash-0.4.5.tar.gz", "has_sig": false, "md5_digest": "d05d98dcd3cd506d70a152ce3af0b99f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2070594, "upload_time": "2014-05-21T23:29:11", "url": "https://files.pythonhosted.org/packages/aa/be/7678a335ee04040e4c7c447d2cba26eecc36ed71bcb952b6b8eecdbd8712/django-dash-0.4.5.tar.gz" } ], "0.4.6": [ { "comment_text": "", "digests": { "md5": "85155b3f5faaae2994836e5005cbd277", "sha256": "cd84ce2ebafb5327b182ab5f782a9e4f3363a82317daf1a498853de93c92cb8d" }, "downloads": -1, "filename": "django-dash-0.4.6.tar.gz", "has_sig": false, "md5_digest": "85155b3f5faaae2994836e5005cbd277", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2071040, "upload_time": "2014-07-10T00:03:35", "url": "https://files.pythonhosted.org/packages/d9/0d/5fd9ecf4a5705331033f3702f53a038e9db5dc5e625db365037a29a667fe/django-dash-0.4.6.tar.gz" } ], "0.4.7": [ { "comment_text": "", "digests": { "md5": "f965411bcfa5f38981216791eaac4475", "sha256": "a6fcdce93feee1ec45629717482b13dbbf72c4c12060f4869758a3595c87f8db" }, "downloads": -1, "filename": "django-dash-0.4.7.tar.gz", "has_sig": false, "md5_digest": "f965411bcfa5f38981216791eaac4475", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2071651, "upload_time": "2014-10-01T00:42:03", "url": "https://files.pythonhosted.org/packages/0a/b3/0bc6680495f5cdb71e7643feeb2f441cec72b8324012463dcaac59b4bc1d/django-dash-0.4.7.tar.gz" } ], "0.4.8": [ { "comment_text": "", "digests": { "md5": "dad921fa6f0fbfc619789946df0227bc", "sha256": "988884afabe2040c759193a39ca7ffb434db5edfab5f0b95eccc4de1b24d92b6" }, "downloads": -1, "filename": "django-dash-0.4.8.tar.gz", "has_sig": false, "md5_digest": "dad921fa6f0fbfc619789946df0227bc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2072627, "upload_time": "2014-10-12T21:20:11", "url": "https://files.pythonhosted.org/packages/ee/f4/1a383fbd43c370510de90303ffcd924d34689ffb7e56d6a97d7ef298bcbf/django-dash-0.4.8.tar.gz" } ], "0.4.9": [ { "comment_text": "", "digests": { "md5": "31f63b676fcae4a7a4fb493127efbeba", "sha256": "ffdb86ed5739cbdc21d75c2247c53915ad32b40b8226096172a92fb6fee740ed" }, "downloads": -1, "filename": "django-dash-0.4.9.tar.gz", "has_sig": false, "md5_digest": "31f63b676fcae4a7a4fb493127efbeba", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2065566, "upload_time": "2014-11-22T02:22:28", "url": "https://files.pythonhosted.org/packages/85/55/03ffaaace3bccc9284b97b0e5557498537d98907a2efbbd74e0b4f7c82bf/django-dash-0.4.9.tar.gz" } ], "0.5": [ { "comment_text": "", "digests": { "md5": "f3384583dea8dea2a7d0bb1c222e774b", "sha256": "cf0bb0b101a524b2bcc071a5a6271a720e10a8ecd8c321a3813c7365ecf5efd3" }, "downloads": -1, "filename": "django_dash-0.5-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "f3384583dea8dea2a7d0bb1c222e774b", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 1253937, "upload_time": "2017-03-11T22:25:58", "url": "https://files.pythonhosted.org/packages/55/83/ba8c6c921a7c3d0e0439939bc7d80027b5c8862c7efec0bfecafa75ba544/django_dash-0.5-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ad7669425870bad73eb92d18e94e6461", "sha256": "bda55694728245fb22e36ebce1058faf65e01de4aeeecbd342f75f41a8aad481" }, "downloads": -1, "filename": "django-dash-0.5.tar.gz", "has_sig": false, "md5_digest": "ad7669425870bad73eb92d18e94e6461", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1169760, "upload_time": "2017-03-11T22:25:53", "url": "https://files.pythonhosted.org/packages/7a/e7/4f4261849ee50df6ce5a67395f8bc70be1862b0895fa5633d47cfda01af8/django-dash-0.5.tar.gz" } ], "0.5.1": [ { "comment_text": "", "digests": { "md5": "2f1434a70b4ada898bbcf36c0f084d36", "sha256": "983350f98d90f9b8cd7617264410426dd17246fb7643e5f7e511d7a980b1ff47" }, "downloads": -1, "filename": "django_dash-0.5.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "2f1434a70b4ada898bbcf36c0f084d36", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 1253957, "upload_time": "2017-03-12T20:33:48", "url": "https://files.pythonhosted.org/packages/b5/95/c97038f280a51a7caae3ff067662dd66b425db0b9f8292be80a12a60171b/django_dash-0.5.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "99945eac85cee8fdb87f5d7aca2da292", "sha256": "fc59da4872f5e4dcdebb3d1375f2ce3fbf3dd60ec0d98dce8cbd7a1fa6a49187" }, "downloads": -1, "filename": "django-dash-0.5.1.tar.gz", "has_sig": false, "md5_digest": "99945eac85cee8fdb87f5d7aca2da292", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1170614, "upload_time": "2017-03-12T20:33:44", "url": "https://files.pythonhosted.org/packages/ce/ec/60699de09ff57167c3a87f9da9f2ab722cdc2c9c33c280867dc5b6d66bfa/django-dash-0.5.1.tar.gz" } ], "0.5.2": [ { "comment_text": "", "digests": { "md5": "f8708e6ec6ba2247207665969afe77e5", "sha256": "f8a55cbbbdcf9ac45fd6257798636c24e20cc4acaa23c344a84e4193818ebb0c" }, "downloads": -1, "filename": "django_dash-0.5.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "f8708e6ec6ba2247207665969afe77e5", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 1060559, "upload_time": "2017-03-29T22:19:17", "url": "https://files.pythonhosted.org/packages/30/ff/081dbfd1ef359e4d7b722875a9f8e55f88a5735d1814cd3c72d894e53b3d/django_dash-0.5.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "337a03bc20261ad6eeea4334cc124c37", "sha256": "9859edee038327aa4fe5f8084fd903e440982c0377f3cb4ac4575e7cf1227fa9" }, "downloads": -1, "filename": "django-dash-0.5.2.tar.gz", "has_sig": false, "md5_digest": "337a03bc20261ad6eeea4334cc124c37", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 985087, "upload_time": "2017-03-29T22:19:12", "url": "https://files.pythonhosted.org/packages/96/0d/f1a530fc3000027a32d029d7e1f134774f47a3e7212cf6995e6093113415/django-dash-0.5.2.tar.gz" } ], "0.5.3": [ { "comment_text": "", "digests": { "md5": "cdab8c8da71796b4d6156ff5811eae45", "sha256": "3bf669cfebe00aa5d1a8aac1c156a19770518dca3828f1e9b1038c8b6dc17ab4" }, "downloads": -1, "filename": "django_dash-0.5.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "cdab8c8da71796b4d6156ff5811eae45", "packagetype": "bdist_wheel", "python_version": "3.5", "requires_python": null, "size": 1060865, "upload_time": "2017-09-05T20:41:27", "url": "https://files.pythonhosted.org/packages/ca/c5/51d62f5350da48cbebb7950689c87ec950cd6f74ac5ea1590cf5ebed57fb/django_dash-0.5.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6a7dc3410ee7ff1d30b75f1417a44199", "sha256": "71b85cb9c1424615607773cf616d80a7f12ae69e4da456587d53daa54a7059fc" }, "downloads": -1, "filename": "django-dash-0.5.3.tar.gz", "has_sig": false, "md5_digest": "6a7dc3410ee7ff1d30b75f1417a44199", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 979221, "upload_time": "2017-09-05T20:41:23", "url": "https://files.pythonhosted.org/packages/19/b1/351b2c0c57701435adb50ed18c73869846cce39499e8902832c82ab990dc/django-dash-0.5.3.tar.gz" } ], "0.5.4": [ { "comment_text": "", "digests": { "md5": "6f1340dc52142a1f6db10e3e3965a477", "sha256": "d4ceb723b5a6ad4001590887d9e56a1efe61a5348bb82f3d920e4e8710566e57" }, "downloads": -1, "filename": "django_dash-0.5.4-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "6f1340dc52142a1f6db10e3e3965a477", "packagetype": "bdist_wheel", "python_version": "3.5", "requires_python": null, "size": 1061589, "upload_time": "2017-12-27T19:54:10", "url": "https://files.pythonhosted.org/packages/d8/59/5388ddcfc0f98c07e25a012cd49f97a9ade67603b6cea139dcd037e864be/django_dash-0.5.4-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "61032392af41b3d33a348ce8c6496e97", "sha256": "1733f9e2d78a6cb7c2fa3e151b8b5be32d63dd119c767c08165c466a0cebf6e3" }, "downloads": -1, "filename": "django-dash-0.5.4.tar.gz", "has_sig": false, "md5_digest": "61032392af41b3d33a348ce8c6496e97", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 979654, "upload_time": "2017-12-27T19:54:05", "url": "https://files.pythonhosted.org/packages/3b/fe/18ed26f8df4723dbc23cf8f579b0644eae6498f11313f2dde3064c9c4416/django-dash-0.5.4.tar.gz" } ], "0.5.5": [ { "comment_text": "", "digests": { "md5": "e07c47e74da2261fa7d3a2eb857588ab", "sha256": "a080ee8965eed0912c1e526f4be9429fcf2907fdd4e82adf76ba83e96e7b8293" }, "downloads": -1, "filename": "django_dash-0.5.5-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "e07c47e74da2261fa7d3a2eb857588ab", "packagetype": "bdist_wheel", "python_version": "3.5", "requires_python": null, "size": 1061557, "upload_time": "2018-02-09T20:19:31", "url": "https://files.pythonhosted.org/packages/61/2c/e134c5dc70f7cff27ccfef8f4698ee9d6cc8224d37a59656be07c843eac9/django_dash-0.5.5-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "925215f78934eafe6745a7712bfef97d", "sha256": "615e3dbc8b36eb254f04bf81b16de99bdd8722639718e535c725ee784a9becab" }, "downloads": -1, "filename": "django-dash-0.5.5.tar.gz", "has_sig": false, "md5_digest": "925215f78934eafe6745a7712bfef97d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 979824, "upload_time": "2018-02-09T20:19:24", "url": "https://files.pythonhosted.org/packages/91/dc/310807602c4a99b45dc086492ec0d3039df8c3a09518b7911622b05a185b/django-dash-0.5.5.tar.gz" } ], "0.5.6": [ { "comment_text": "", "digests": { "md5": "67cb0501c413c076ec4ad7576b2e30c3", "sha256": "ae4a1117c476f98222018148febb1dc2380ff69f21c168978374fc91ea51505b" }, "downloads": -1, "filename": "django_dash-0.5.6-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "67cb0501c413c076ec4ad7576b2e30c3", "packagetype": "bdist_wheel", "python_version": "3.5", "requires_python": null, "size": 1061552, "upload_time": "2019-08-06T21:06:52", "url": "https://files.pythonhosted.org/packages/bc/4e/46a36f06c5fe3bd34e6f6d52e6aebfef6570d014401647ac5f678b27fb74/django_dash-0.5.6-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6c69ac79904d784955995e01a429e67d", "sha256": "f1021476af369ee5aba3d8e9e96327314439120e56c5bc33c654355389206d9b" }, "downloads": -1, "filename": "django-dash-0.5.6.tar.gz", "has_sig": false, "md5_digest": "6c69ac79904d784955995e01a429e67d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 979844, "upload_time": "2019-08-06T21:06:46", "url": "https://files.pythonhosted.org/packages/82/74/e387cee87b75d2072a8cdce818329901227062146dda6d7ab5439abb6722/django-dash-0.5.6.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "67cb0501c413c076ec4ad7576b2e30c3", "sha256": "ae4a1117c476f98222018148febb1dc2380ff69f21c168978374fc91ea51505b" }, "downloads": -1, "filename": "django_dash-0.5.6-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "67cb0501c413c076ec4ad7576b2e30c3", "packagetype": "bdist_wheel", "python_version": "3.5", "requires_python": null, "size": 1061552, "upload_time": "2019-08-06T21:06:52", "url": "https://files.pythonhosted.org/packages/bc/4e/46a36f06c5fe3bd34e6f6d52e6aebfef6570d014401647ac5f678b27fb74/django_dash-0.5.6-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6c69ac79904d784955995e01a429e67d", "sha256": "f1021476af369ee5aba3d8e9e96327314439120e56c5bc33c654355389206d9b" }, "downloads": -1, "filename": "django-dash-0.5.6.tar.gz", "has_sig": false, "md5_digest": "6c69ac79904d784955995e01a429e67d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 979844, "upload_time": "2019-08-06T21:06:46", "url": "https://files.pythonhosted.org/packages/82/74/e387cee87b75d2072a8cdce818329901227062146dda6d7ab5439abb6722/django-dash-0.5.6.tar.gz" } ] }