{ "info": { "author": "S. Andrew Sheppard", "author_email": "andrew@wq.io", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Framework :: Django", "Framework :: Django :: 1.11", "Framework :: Django :: 1.8", "Framework :: Django :: 2.0", "Framework :: Django :: 2.1", "Framework :: Django :: 2.2", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Programming Language :: JavaScript", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Database :: Database Engines/Servers", "Topic :: Scientific/Engineering :: GIS" ], "description": "**Django Data Wizard** is an interactive tool for mapping tabular data (e.g. Excel, CSV, XML, JSON) into a normalized database structure via [Django REST Framework] and [wq.io]. Django Data Wizard allows novice users to map spreadsheet columns to serializer fields (and cell values to foreign keys) on-the-fly during the import process. This reduces the need for preset spreadsheet formats, which most data import solutions require.\n\n\"Column\n\"Auto\n\"Imported\n\nThe Data Wizard supports straightforward one-to-one mappings from spreadsheet columns to database fields, as well as more complex scenarios like [natural keys] and [Entity-Attribute-Value] (or \"wide\") table mappings. It was originally developed for use with the [ERAV data model][ERAV] provided by [vera].\n\n[![Latest PyPI Release](https://img.shields.io/pypi/v/data-wizard.svg)](https://pypi.org/project/data-wizard)\n[![Release Notes](https://img.shields.io/github/release/wq/django-data-wizard.svg)](https://github.com/wq/django-data-wizard/releases)\n[![License](https://img.shields.io/pypi/l/data-wizard.svg)](https://wq.io/license)\n[![GitHub Stars](https://img.shields.io/github/stars/wq/django-data-wizard.svg)](https://github.com/wq/django-data-wizard/stargazers)\n[![GitHub Forks](https://img.shields.io/github/forks/wq/django-data-wizard.svg)](https://github.com/wq/django-data-wizard/network)\n[![GitHub Issues](https://img.shields.io/github/issues/wq/django-data-wizard.svg)](https://github.com/wq/django-data-wizard/issues)\n\n[![Travis Build Status](https://img.shields.io/travis/wq/django-data-wizard.svg)](https://travis-ci.org/wq/django-data-wizard)\n[![Python Support](https://img.shields.io/pypi/pyversions/data-wizard.svg)](https://pypi.org/project/data-wizard)\n[![Django Support](https://img.shields.io/pypi/djversions/data-wizard.svg)](https://pypi.org/project/data-wizard)\n\n# Usage\n\nDjango Data Wizard provides a [web interface](#api-documentation), [JSON API](#api-documentation), and [CLI](#command-line-interface) for specifying a [data source](#custom-data-sources) to import (e.g. a previously-uploaded file), selecting a [serializer](#custom-serializers), mapping the data [columns](#columns) and [identifiers](#ids), and (asynchronously) importing the [data](#data) into the database.\n\n## Installation\n\n```bash\n# Recommended: create virtual environment\n# python3 -m venv venv\n# . venv/bin/activate\n\npip install data-wizard\n```\n\nSee to report any issues.\n\n## Initial Configuration\n\nWithin a new or existing Django project, add `data_wizard` to your `INSTALLED_APPS`:\n\n```python\n# myproject/settings.py\nINSTALLED_APPS = (\n # ...\n 'data_wizard',\n 'data_wizard.sources', # Optional\n)\n\n# This can be omitted to use the defaults\nDATA_WIZARD = {\n 'BACKEND': 'data_wizard.backends.threading',\n 'LOADER': 'data_wizard.loaders.FileLoader',\n 'PERMISSION': 'rest_framework.permissions.IsAdminUser',\n}\n```\n\nIf you would like to use the built-in data source tables (`FileSource` and `URLSource`), also include `data_wizard.sources` in your `INSTALLED_APPS`. Otherwise, you will want to configure one or more [custom data sources (see below)](#custom-data-sources).\n\n> Note: In version 1.1.0 and later, Django Data Wizard uses a simple [threading backend](#data_wizardbackendsthreading) for executing asynchronous tasks. The old [celery backend](#data_wizardbackendscelery) can also be used but this is no longer required.\n\n\nNext, add `\"data_wizard.urls\"` to your URL configuration.\n\n```python\n# myproject/urls.py\nfrom django.urls import path, include\n\nurlpatterns = [\n # ...\n path('datawizard/', include('data_wizard.urls')),\n]\n```\n\n> Note: If you are upgrading from 1.0, you will need to update your URLs to add the `datawizard/` prefix as shown above.\n\n### Model Registration\n\nIn order to use the wizard, you must register one or more target models and/or serializers. Like the Django admin and `admin.py`, Data Wizard will look for a `wizard.py` file in your app directory:\n\n```python\n# myapp/wizard.py\nimport data_wizard\nfrom .models import MyModel\n\ndata_wizard.register(MyModel)\n```\n\nThe wizard will automatically create a serializer class corresponding to the target model. If needed, you can also use a [custom serializer class](#custom-serializers) to configure how the target model is validated and populated.\n\nOnce everything is configured, create a data source in the Django admin, select \"Import via data wizard\" from the admin actions menu, and navigate through the screens described below.\n\n## API Documentation\n\nDjango Data Wizard is implemented as a series of views that can be accessed via the Django admin as well as via a JSON API.\n\n---\n\n\"Select\n\n### New Run\n\n#### `POST /datawizard/`\n\nCreates a new instance of the wizard (i.e. a `Run`). If you are using the Django admin integration, this step is executed when you select \"Import via Data Wizard\" from the admin actions menu. If you are using the JSON API, the returned run `id` should be used in all subsequent calls to the API. Each `Run` is tied to the model containing the actual data via a [generic foreign key].\n\nparameter | description\n------------------|----------------------------------------\n`object_id` | The id of the object containing the data to be imported.\n`content_type_id` | The app label and model name of the referenced model (in the format `app_label.modelname`).\n`loader` | (Optional) The class name to use for loading the dataset via wq.io. The default loader (`data_wizard.loaders.FileLoader`) assumes that the referenced model contains a `FileField` named `file`.\n`serializer` | (Optional) The class name to use for serialization. This can be left unset to allow the user to select it during the wizard run.\n\n---\n\n\"Auto\n\n### auto\n#### `POST /datawizard/[id]/auto`\n\nThe `auto` task attempts to run the entire data wizard process from beginning to end. If any input is needed, the import will halt and redirect to the necessary screen. If no input is needed, the `auto` task is equivalent to starting the `data` task directly. This is an asynchronous method, and returns a `task_id` to be used with the status API.\n\nThe [run_detail.html] template provides an example form that initiates the `auto` task. The `auto` task itself uses the [run_auto.html] template. \n\n---\n\n### status\n#### `GET /datawizard/[id]/status.json?task=[task]`\n\nThe `status` API is used to check the status of an asynchronous task (one of `auto` or `data`). The API is used by the provided [data_wizard/js/progress.js] to update the `` bar in the [run_auto.html] and [run_data.html] templates. Unlike the other methods, this API is JSON-only and has no HTML equivalent. An object of the following format will be returned:\n\n```js\n{\n // General properties\n \"status\": \"PROGRESS\", // or \"SUCCESS\", \"FAILURE\"\n \"stage\": \"meta\", // or \"data\"\n \"current\": 23, // currently processing row\n \"total\": 100, // total number of rows\n\n // \"FAILURE\"\n \"error\": \"Error Message\",\n\n // Task complete (\"SUCCESS\")\n \"action\": \"records\", // or \"serializers\", \"columns\" \"ids\"\n \"message\": \"Input Needed\", // if action is not \"records\"\n \"skipped\": [...], // rows that could not be imported\n \"location\": \"/datawizard/[id]/records\",\n}\n```\n\nThe potential values for the `status` field are the same as common [Celery task states], even when not using the `celery` backend. When running an `auto` task, the result is `SUCCESS` whenever the task ends without errors, even if there is additional input needed to fully complete the run.\n\nThe default [run_auto.html] and [run_data.html] templates include a `` element for use with the status task.\n\n---\n\n\"Serializer\n\n### serializers\n#### `GET /datawizard/[id]/serializers`\n\nThe `serializers` task provides a list of all registered serializers. This screen is shown by the `auto` task if a serializer was not specified when the `Run` was created. The default [run_serializers.html] template includes an interface for selecting a registered serializer. If a serializer is already selected, the template will display the label and a button to (re)start the `auto` task.\n\n
\n\n---\n\n\"Serializer\n\n### updateserializer\n#### `POST /datawizard/[id]/updateserializer`\n\nThe `updateserializer` task updates the specified `Run` with the selected serializer class name. This is typically called from [the form][run_serializers.html] generated by the `serializers` task, and will redirect to that task when complete.\n\nparameter | description\n-------------|----------------------------------------\n`serializer` | The class name (or label) of the serializer to use for this run.\n\n---\n\n\"Column\n\n### columns\n#### `GET /datawizard/[id]/columns`\n\nThe `columns` task lists all of the columns found in the dataset (i.e. spreadsheet) and their mappings to serializer fields. This screen is shown by the `auto` task if there are any column names that could not be automatically mapped. The potential mappings are one of:\n\n * simple serializer field names (e.g. `field`)\n * nested field names (for [natural keys], e.g. `nested[record][field]`)\n * [EAV][Entity-Attribute-Value] attribute-value mappings (e.g. `values[][value];attribute_id=1`).\n\nTo enable a natural key mapping, the registered serializer should be an instance of `NaturalKeyModelSerializer`, as in [this example][naturalkey_wizard]. To enable an EAV mapping, the registered serializer should include a nested serializer with `many=True` and at least one foreign key to the attribute table, as in [this example][eav_wizard].\n\nThe default [run_columns.html] template includes an interface for mapping data columns to serializer fields. If all columns are already mapped, the template will display the mappings and a button to (re)start the `auto` task.\n\n---\n\n\"Columns\n\n### updatecolumns\n#### `POST /datawizard/[id]/updatecolumns`\n\nThe `updatecolumns` task saves the specified mappings from data columns to serializer fields. This is typically called from [the form][run_columns.html] generated by the `columns` task, and will redirect to that task when complete.\n\nparameter | description\n--------------|----------------------------------------\n`rel_[relid]` | The column to map to the specified serializer field. The `relid` and the complete list of possible mappings will be provided by the `columns` task.\n\n---\n\n\"Identifier\n\n### ids\n#### `GET /datawizard/[id]/ids`\n\nThe `ids` task lists all of the identifiers found in the dataset (i.e. spreadsheet) that are in a column known to correspond to a foreign key. This screen is shown by the `auto` task if there are any identifiers that could not be automatically mapped to foreign key values. The potential mappings depend on the serializer field used to represent the foreign key.\n\n * Existing record ID or slug (for [PrimaryKeyRelatedField], [SlugRelatedField], and [NaturalKeySerializer][natural keys])\n * `\"new\"` (`NaturalKeySerializer` only)\n\nThe primary difference is that `NaturalKeySerializer` allows for the possibility of creating new records in the foreign table on the fly, while the regular related fields do not.\n\nThe default [run_ids.html] template includes an interface for mapping row identifiers to foreign key values. If all ids are already mapped (or indicated to be new natural keys), the template will display the mappings and a button to (re)start the `auto` task.\n\n---\n\n\"Identifiers\n\n### updateids\n#### `POST /datawizard/[id]/updateids`\n\nThe `updateids` task saves the specified mappings from row identifiers to foreign key values. This is typically called from [the form][run_ids.html] generated by the `ids` task, and will redirect to that task when complete.\n\nparameter | description\n---------------------|----------------------------------------\n`ident_[identid]_id` | The identifier to map to the specified foreign key value. The `identid` and the complete list of possible mappings will be provided by the `ids` task.\n\n---\n\n\"Auto\n\n### data\n#### `POST /datawizard/[id]/data`\n\nThe `data` task starts the actual import process (and is called by `auto` behind the scenes). Unlike `auto`, calling `data` directly will not cause a redirect to one of the other tasks if any meta input is needed. Instead, `data` will attempt to import each record as-is, and report any errors that occured due to e.g. missing fields or unmapped foreign keys.\n\nThis is an asynchronous method, and returns a `task_id` to be used with the `status` API. The default [run_data.html] template includes a `` element for use with status task.\n\n---\n\n\"Imported\n\n### records\n#### `GET /datawizard/[id]/records`\n\nThe `records` task provides a list of imported rows (including errors). It is redirected to by the `auto` and `data` tasks upon completion. When possible, the `records` task includes links to the `get_absolute_url()` or to the admin screen for each newly imported record. The default [run_records.html] template includes an interface for displaying the record details.\n\n
\n\n---\n\n\"Run\n\n### Run List\n#### `GET /datawizard/`\n\nDjango Data Wizard provides a list view that summarises prior runs and the number of records imported by each. Incomplete runs can also be restarted from this list.\n\n

\n\n---\n\n\"Identifier\n\n### Identifier Admin\n#### `GET /admin/data_wizard/identifer/`\n\nAs of version 1.1.0, Django Data Wizard identifier mappings can be viewed and edited via the Django Admin. Runs can also be viewed through the admin - though the Run List above will generally be more useful.\n\n
\n\n## Command-Line Interface\n\nDjango Data Wizard provides a single [management command], `runwizard`, that can be used to initiate the `auto` task from the command line. This can be used to facilitate automated processing, for example as part of a regular cron job. Note that the CLI does not (currently) support interactively mapping columns and ids, so these should be pre-mapped using the web or JSON API.\n\nUsage:\n\n```bash\n./manage.py runwizard myapp.mymodel 123 \\\n --loader myapp.loaders.customloader \\\n --serializer myapp.serializer.customserializer \\\n --username myusername\n```\n\nThe basic usage is similar to the [New Run API](#new-run). Only a content type and object id are required, while the other arguments will be auto-detected if possible. In particular, you may want to use [set_loader()](#custom-loader) to predefine the default `loader` and `serializer` for any models you plan to use with the CLI.\n\nThe `runwizard` command will create a new `Run` and immediately start the `auto` task. Errors will be shown on the console.\n\n## Custom Serializers\n\nData Wizard uses instances of Django REST Framework's [Serializer class][ModelSerializer] to determine the destination fields on the database model. Specifically, the default serializer is [NaturalKeyModelSerializer], which is based on [ModelSerializer].\n\nYou can override the default serializer by calling `data_wizard.register()` with a name and a serializer class instead of a model class. Multiple serializers can be registered with the wizard to support multiple import configurations and destination models. \n\n```python\n# myapp/wizard.py\nfrom rest_framework import serializers\nimport data_wizard\nfrom .models import TimeSeries\n\n\nclass TimeSeriesSerializer(serializers.ModelSerializer):\n # (custom fields here)\n class Meta:\n model = TimeSeries\n fields = '__all__'\n\n # Optional - see options below\n data_wizard = {\n 'header_row': 0,\n 'start_row': 1,\n 'show_in_list': True,\n }\n\n# Use default name & serializer\ndata_wizard.register(TimeSeries)\n\n# Use custom name & serializer\ndata_wizard.register(\"Time Series - Custom Serializer\", TimeSeriesSerializer)\n```\n\nAt least one serializer or model should be registered in order to use the wizard. Note the use of a human-friendly serializer label when registering a serializer. This name should be unique throughout the project, but can be changed later on without breaking existing data. (The class path is used as the actual identifier behind the scenes.)\n\n### Serializer Options\n\nData Wizard also supports custom configuration by setting a `data_wizard` attribute on the `Meta` class of the serializer. The following options are supported.\n\nname | default | notes\n--|--|--\n`header_row` | 0 | Specifies the first row of the spreadsheet that contains column headers. If this is greater than 0, the space above the column headers will be scanned for anything that looks like a one-off \"global\" value intended to be applied to every row in the imported data.\n`start_row` | 1 | The first row of data. If this is greater than `header_row + 1`, the column headers will be assumed to span multiple rows. A common case is when parameter hames are on the first row and units are on the second.\n`show_in_list` | `True` | **New in 1.2**. If set to `False`, the serializer will be available through the API but not listed in the wizard views. This is useful if you have a serializer that should only be used during fully automated workflows.\n\n## Custom Data Sources\n\nDjango Data Wizard uses [wq.io] to determine the source columns present on the spreadsheet or other data source. Django Data Wizard can use any Django model instance as a source for its data, provided there is a registered loader that can convert the source model into a [wq.io] iterable. Data Wizard provides two out-of-the the box loaders, [FileLoader] and [URLLoader], that can be used with the provided models in `data_wizard.sources` (`FileSource` and `URLSource`, respectively).\n\n### Extending FileLoader\nThe default `FileLoader` can be used with any Django model with a `FileField` named `file`. You can use a model with a different `FileField` name by creating a subclass of `data_wizard.loaders.FileLoader` and setting it as the loader for your model.\n\n```python\n# myapp/models.py\nfrom django.db import models\n\nclass FileModel(models.Model):\n spreadsheet = models.FileField(upload_to='spreadsheets')\n```\n\n```python\n# myapp/loaders.py\nfrom data_wizard import loaders\n\nclass FileLoader(loaders.FileLoader):\n file_attr = 'spreadsheet'\n```\n\n```python\n# myapp/wizard.py\nimport data_wizard\nfrom .models import FileModel\n\ndata_wizard.set_loader(FileModel, \"myapp.loaders.FileLoader\")\n```\n\nIf you have a generic loader that can work with multiple source models, you can also set the default loader globally:\n\n```python\n# myapp/settings.py\nDATA_WIZARD = {\n 'LOADER': 'myapp.loaders.FileLoader'\n}\n```\n\nAs of Django Data Wizard 1.2, you should register a custom `ModelAdmin` class to add the Import action in the admin panel for your model.\n\n```python\n# myapp/admin.py\nfrom django.contrib import admin\nfrom data_wizard.admin import ImportActionModelAdmin\n\nfrom .models import FileModel\n\n\n@admin.register(FileModel)\nclass FileModelAdmin(ImportActionModelAdmin):\n pass\n```\n\n### Custom Loader\nThe default loaders support any file format supported by [wq.io] (Excel, CSV, JSON, and XML). Additional formats can be integrating by creating a [custom wq.io class] and then registering it with the wizard. For example, the [Climata Viewer] uses Django Data Wizard to import data from [climata]'s wq.io-based web service client. To do this, extend `data_wizard.loaders.BaseLoader` with a custom `load_io()` function that returns the data from wq.io, as in the example below.\n\nIt is likely that you will want to use a specific serializer with your custom loader. If so, override `default_serializer` or `get_serializer_name()` on the loader. By default, these return `None`, which requires the user to specify the serializer when creating or executing the `Run`.\n\n```python\n# myapp/models.py\nfrom django.db import models\n\nclass CustomIOSource(models.Model):\n some_option = models.TextField()\n```\n\n```python\n# myapp/loaders.py\nfrom data_wizard import loaders\nfrom .io import CustomIO\n\nclass CustomIOLoader(loaders.BaseLoader):\n default_serializer = 'mydataapp.wizard.CustomSerializer'\n def load_io(self):\n source = self.run.content_object\n return CustomIO(some_option=source.some_option)\n```\n\n```python\n# myapp/wizard.py\nimport data_wizard\nfrom .models import CustomIOSource\n\ndata_wizard.set_loader(CustomIOSource, \"myapp.loaders.CustomIOLoader\")\n```\n\n\n## Task Backends\n\nAs of version 1.1.0, Django Data Wizard **no longer requires** the use of `celery` as a task runner. Any of the following backends can be configured with via the `BACKEND` setting:\n\n```python\n# myproject/settings.py\n\nDATA_WIZARD = {\n \"BACKEND\": \"data_wizard.backends.threading\" # Default in 1.1.x\n \"data_wizard.backends.immediate\"\n \"data_wizard.backends.celery\" # Only choice in 1.0.x\n}\n```\n\nFor backwards compatibility with 1.0.x, the default backend reverts to `celery` if you have `CELERY_RESULT_BACKEND` defined in your project settings. However, it is recommended to explicitly set `BACKEND`, as this behavior may change in a future major version of Data Wizard.\n\n### `data_wizard.backends.threading`\n\nThe `threading` backend creates a separate thread for long-running asynchronous tasks (i.e. `auto` and `data`). The threading backend leverages the Django cache to pass results back to the status API. As of Django Data Wizard 1.1.0, **this backend is the default** unless you have configured Celery.\n\n### `data_wizard.backends.immediate`\n\nThe `immediate` backend completes all processing before returning a result to the client, even for the otherwise \"asynchronous\" tasks (`auto` and `data`). This backend is suitable for small spreadsheets, or for working around threading issues. This backend maintains minimal state, and is not recommended for use cases involving large spreadsheets or multiple simultanous import processes.\n\n### `data_wizard.backends.celery`\n\nThe `celery` backend leverages [Celery] to handle asynchronous tasks, and is usually used with [Redis] as the memory store.\n**Celery is no longer required to use Django Data Wizard,** unless you would like to use the `celery` backend. If so, be sure to configure these libraries first or the REST API may not work as expected. You can use these steps on Ubuntu:\n\n```bash\n# Install redis and celery\nsudo apt-get install redis-server\npip install celery redis\n```\n\nOnce Redis is installed, configure the following files in your project:\n```python\n# myproject/settings.py\nDATA_WIZARD {\n 'BACKEND': 'data_wizard.backends.celery'\n}\nCELERY_RESULT_BACKEND = BROKER_URL = 'redis://localhost:6379/1'\n\n# myproject/celery.py\nfrom __future__ import absolute_import\nfrom celery import Celery\nfrom django.conf import settings\napp = Celery('myproject')\napp.config_from_object('django.conf:settings')\napp.autodiscover_tasks(lambda: settings.INSTALLED_APPS)\n\n# myproject/__init__.py\nfrom .celery import app as celery_app\n```\n\nFinally, run celery with `celery -A myproject`. You may want to use celery's [daemonization] to keep the process running in the background. Any time you change your serializer registration, be sure to reload celery in addition to restarting the Django WSGI instance.\n\n> Note that the requirement for an extra daemon means this backend can break more easily after a server restart. Even worse, you may not notice that the backend is down for several months (e.g. until a user tries to import a spreadsheet). For this reason, **we recommend using one of the other backends** unless you are already using celery for other background processing tasks.\n\n## wq Framework integration\n\nThe Django Data Wizard has built-in support for integration with the [wq framework]. Configuration is mostly the same, except that you do not need to add `\"data_wizard.urls\"` to your urls.py as the wizard with register itself with [wq.db] instead.\n\nData Wizard includes mustache templates for each of the above tasks to integrate with the wq.app UI. Be sure to enable the [wq/progress.js] plugin for use with the `run_auto.html` and `run_data.html` template. You could allow the user to initiate an import run by adding the following to the detail HTML for your model:\n\n```html\n\n

{{label}}

\nDownload File\n\n
\n {{>csrf}}\n \n \n \n
\n```\n\n```javascript\n// myapp/main.js\ndefine(['wq/app', 'wq/progress', ...],\nfunction(app, progress, ...) {\n app.use(progress);\n app.init(config).then(...);\n});\n```\n\n[wq.io]: https://wq.io/wq.io\n[Django REST Framework]: http://www.django-rest-framework.org/\n[natural keys]: https://github.com/wq/django-natural-keys\n[Entity-Attribute-Value]: https://wq.io/docs/eav-vs-relational\n[ERAV]: https://wq.io/docs/erav\n[vera]: https://wq.io/vera\n\n[wq.db]: https://wq.io/wq.db\n[custom wq.io class]: https://wq.io/docs/custom-io\n[Climata Viewer]: https://github.com/heigeo/climata-viewer\n[climata]: https://github.com/heigeo/climata\n[wq framework]: https://wq.io/\n[wq.db.rest]: https://wq.io/docs/about-rest\n[ModelSerializer]: http://www.django-rest-framework.org/api-guide/serializers/#modelserializer\n[NaturalKeyModelSerializer]: https://github.com/wq/django-natural-keys#naturalkeymodelserializer\n[FileLoader]: https://github.com/wq/django-data-wizard/blob/master/data_wizard/loaders.py\n[URLLoader]: https://github.com/wq/django-data-wizard/blob/master/data_wizard/loaders.py\n[generic foreign key]: https://docs.djangoproject.com/en/1.11/ref/contrib/contenttypes/\n[data_wizard/js/progress.js]: https://github.com/wq/django-data-wizard/blob/master/data_wizard/static/data_wizard/js/progress.js\n[wq/progress.js]: https://wq.io/docs/progress-js\n[Celery]: http://www.celeryproject.org/\n[Redis]: https://redis.io/\n[daemonization]: http://docs.celeryproject.org/en/latest/userguide/daemonizing.html\n[wq.app]: https://wq.io/wq.app\n[Celery task states]: http://docs.celeryproject.org/en/latest/userguide/tasks.html#task-states\n\n[PrimaryKeyRelatedField]: http://www.django-rest-framework.org/api-guide/relations/#primarykeyrelatedfield\n[SlugRelatedField]: http://www.django-rest-framework.org/api-guide/relations/#slugrelatedfield\n\n[run_detail.html]: https://github.com/wq/django-data-wizard/blob/master/data_wizard/templates/data_wizard/run_detail.html\n[run_auto.html]: https://github.com/wq/django-data-wizard/blob/master/data_wizard/templates/data_wizard/run_auto.html\n[run_serializers.html]: https://github.com/wq/django-data-wizard/blob/master/data_wizard/templates/data_wizard/run_serializers.html\n[run_columns.html]: https://github.com/wq/django-data-wizard/blob/master/data_wizard/templates/data_wizard/run_columns.html\n[run_ids.html]: https://github.com/wq/django-data-wizard/blob/master/data_wizard/templates/data_wizard/run_ids.html\n[run_data.html]: https://github.com/wq/django-data-wizard/blob/master/data_wizard/templates/data_wizard/run_data.html\n[run_records.html]: https://github.com/wq/django-data-wizard/blob/master/data_wizard/templates/data_wizard/run_records.html\n\n[naturalkey_wizard]: https://github.com/wq/django-data-wizard/blob/master/tests/naturalkey_app/wizard.py\n[eav_wizard]: https://github.com/wq/django-data-wizard/blob/master/tests/eav_app/wizard.py\n[management command]: https://docs.djangoproject.com/en/2.1/ref/django-admin/\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/wq/django-data-wizard", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "data-wizard", "package_url": "https://pypi.org/project/data-wizard/", "platform": "", "project_url": "https://pypi.org/project/data-wizard/", "project_urls": { "Homepage": "https://github.com/wq/django-data-wizard" }, "release_url": "https://pypi.org/project/data-wizard/1.2.0/", "requires_dist": [ "djangorestframework", "wq.io", "natural-keys", "html-json-forms", "python-dateutil" ], "requires_python": "", "summary": "Interactive web-based wizard to facilitate importing structured data into Django models.", "version": "1.2.0" }, "last_serial": 5768776, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "606585319078f94069bcd4d663ce68cb", "sha256": "1ddbc42e5cb24bfffb0bda4beed9c670ef5da0beedb4032417346095fdd0dd7b" }, "downloads": -1, "filename": "data-wizard-1.0.0.tar.gz", "has_sig": false, "md5_digest": "606585319078f94069bcd4d663ce68cb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 33656, "upload_time": "2017-07-31T21:47:05", "url": "https://files.pythonhosted.org/packages/37/f8/d8f1c261513673fb9e7a65de6bde2534e46ffb91117d42afd22811d0f1a6/data-wizard-1.0.0.tar.gz" } ], "1.0.0b1": [ { "comment_text": "", "digests": { "md5": "d629a87e23c09b459648884f9aad81b3", "sha256": "9d6b839c94c26816c3cfdddc857c41fa8e7b633ff32032ad10c3201e6977eb73" }, "downloads": -1, "filename": "data-wizard-1.0.0b1.tar.gz", "has_sig": false, "md5_digest": "d629a87e23c09b459648884f9aad81b3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13899, "upload_time": "2016-09-08T18:25:58", "url": "https://files.pythonhosted.org/packages/21/60/c2fbd47f54bcb498cb93a0cfa3ecf4e8f3565c5d2d0f8bc14d1e4ed96f87/data-wizard-1.0.0b1.tar.gz" } ], "1.0.0b2": [ { "comment_text": "", "digests": { "md5": "5be30c4b6d0d586255b3fa2e459aefeb", "sha256": "75c38810e71ed89cacae29d7d928e00403a910139588f04a7e84129436ca0d06" }, "downloads": -1, "filename": "data-wizard-1.0.0b2.tar.gz", "has_sig": false, "md5_digest": "5be30c4b6d0d586255b3fa2e459aefeb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15647, "upload_time": "2016-11-08T22:22:09", "url": "https://files.pythonhosted.org/packages/67/f9/217d2e50cb26d1089b73e6d1af7db73c95ebb87af3797c06df40dc414c9d/data-wizard-1.0.0b2.tar.gz" } ], "1.0.0rc1": [ { "comment_text": "", "digests": { "md5": "0789e01fdd7e009a1b18b497256c09ab", "sha256": "636dd89fc17e3232af0ef5c744c2afbfb9cd3880fd06c03570eb6de5ddda1dd8" }, "downloads": -1, "filename": "data-wizard-1.0.0rc1.tar.gz", "has_sig": false, "md5_digest": "0789e01fdd7e009a1b18b497256c09ab", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25212, "upload_time": "2017-06-16T16:05:47", "url": "https://files.pythonhosted.org/packages/d9/c4/b1c6639b412f1f751faef2c80dbc95cd8ea6538106f5f6ea6ee64c285ea7/data-wizard-1.0.0rc1.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "0cfe484f1cca211fee3fe02c09e5ad18", "sha256": "f3cdcd87edea3dbef8fb6e23ca25d6be9fe1be14f50005bf92d9724689c13cbc" }, "downloads": -1, "filename": "data-wizard-1.0.1.tar.gz", "has_sig": false, "md5_digest": "0cfe484f1cca211fee3fe02c09e5ad18", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 33637, "upload_time": "2017-09-12T20:17:56", "url": "https://files.pythonhosted.org/packages/9c/41/14688985fbbfaf90c92d179a1e86dc365122a01ca444a13b9078cd1ef93b/data-wizard-1.0.1.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "42edcc26c33ed58e2a75ae362d027907", "sha256": "fb2debe3558525c27a8cc5be82f662ab14c2bfb788d0d80f743e64976acdb8d1" }, "downloads": -1, "filename": "data_wizard-1.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "42edcc26c33ed58e2a75ae362d027907", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 54622, "upload_time": "2019-03-15T02:33:43", "url": "https://files.pythonhosted.org/packages/dc/ec/b8f664ac91e719cbd929696cdb0c70041511dcd780cbcb941f46f26642f7/data_wizard-1.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b53c95293b2ee8d9be165be4558b2629", "sha256": "5794ee5cbcde45009ad1d9356075effdfab67e166da352286ace5117944db1da" }, "downloads": -1, "filename": "data-wizard-1.1.0.tar.gz", "has_sig": false, "md5_digest": "b53c95293b2ee8d9be165be4558b2629", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 573674, "upload_time": "2019-03-15T02:33:45", "url": "https://files.pythonhosted.org/packages/9a/c1/c8a83e6d9ce22962c64e6ae3cd411fbb1134aa688f7499c3bd6a8e8e9c6e/data-wizard-1.1.0.tar.gz" } ], "1.2.0": [ { "comment_text": "", "digests": { "md5": "4f3677c3452078636c6fbbaaa6e48a28", "sha256": "591093e4de8c7f763acccb8cccb85a5b7d10f8a68cb4a76f5d49d0563c8a30e0" }, "downloads": -1, "filename": "data_wizard-1.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "4f3677c3452078636c6fbbaaa6e48a28", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 55827, "upload_time": "2019-09-02T03:32:07", "url": "https://files.pythonhosted.org/packages/23/a5/0c656db9e2f506c2e8395cb70cfa3a21882d5a22f07d95361b4753d0dd5c/data_wizard-1.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8811d51eab583e8ae34744b33e9dca41", "sha256": "800b88da2ae764e10dfadb5a2ff878a0d679d3b0405f066b57b0f44125dee2ec" }, "downloads": -1, "filename": "data-wizard-1.2.0.tar.gz", "has_sig": false, "md5_digest": "8811d51eab583e8ae34744b33e9dca41", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 800800, "upload_time": "2019-09-02T03:32:10", "url": "https://files.pythonhosted.org/packages/95/14/75597ecb7c0e0724985404bb30c8e91db6013069990d33266d346794dcb7/data-wizard-1.2.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "4f3677c3452078636c6fbbaaa6e48a28", "sha256": "591093e4de8c7f763acccb8cccb85a5b7d10f8a68cb4a76f5d49d0563c8a30e0" }, "downloads": -1, "filename": "data_wizard-1.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "4f3677c3452078636c6fbbaaa6e48a28", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 55827, "upload_time": "2019-09-02T03:32:07", "url": "https://files.pythonhosted.org/packages/23/a5/0c656db9e2f506c2e8395cb70cfa3a21882d5a22f07d95361b4753d0dd5c/data_wizard-1.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8811d51eab583e8ae34744b33e9dca41", "sha256": "800b88da2ae764e10dfadb5a2ff878a0d679d3b0405f066b57b0f44125dee2ec" }, "downloads": -1, "filename": "data-wizard-1.2.0.tar.gz", "has_sig": false, "md5_digest": "8811d51eab583e8ae34744b33e9dca41", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 800800, "upload_time": "2019-09-02T03:32:10", "url": "https://files.pythonhosted.org/packages/95/14/75597ecb7c0e0724985404bb30c8e91db6013069990d33266d346794dcb7/data-wizard-1.2.0.tar.gz" } ] }