# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['django_reactive', 'django_reactive.widget']

package_data = \
{'': ['*'],
 'django_reactive': ['static/css/*',
                     'static/dist/*',
                     'static/js/*',
                     'templates/*']}

install_requires = \
['django>=2.2,<4.0',
 'jsonschema>=3.0,<4.0',
 'psycopg2-binary>=2.7,<3.0',
 'pytest-cov>=2.10.1,<3.0.0',
 'pytest-django>=4.1.0,<5.0.0',
 'pytest>=6.1.2,<7.0.0']

setup_kwargs = {
    'name': 'django-reactive',
    'version': '0.0.8',
    'description': 'Django JSON form field on steroids using react-json-schema-form',
    'long_description': '=============================\ndjango-reactive\n=============================\n\n.. image:: https://badge.fury.io/py/django-reactive.svg\n    :target: https://badge.fury.io/py/django-reactive\n\n.. image:: https://github.com/tyomo4ka/django-reactive/workflows/CI/badge.svg?branch=master\n    :target: https://github.com/tyomo4ka/django-reactive/actions\n\n.. image:: https://codecov.io/gh/tyomo4ka/django-reactive/branch/master/graph/badge.svg\n    :target: https://codecov.io/gh/tyomo4ka/django-reactive\n\ndjango-reactive integrates `react-jsonschema-form <https://github.com/mozilla-services/react-jsonschema-form>`_ (RJSF)\nin Django projects.\n\nMotivation\n----------\n\n`JSON types <https://www.postgresql.org/docs/10/datatype-json.html>`_ is a cool feature of\nPostgres that allows combining both relational and non-relational approaches to storing data together. In most cases\nit would lead to a simpler database design.\n\nThe `JSONField  <https://docs.djangoproject.com/en/2.1/ref/contrib/postgres/fields/#jsonfield>`_ in Django provides a\nnice way of integrating **json** and **jsonb** Postgres types inside the ORM. ORM can even utilise JSON fields\nto perform database queries. **jsonb** type also offers indexing for JSON documents. That makes it a powerful\ntool in the application design and opens a wide range of use cases, e.g. polymorphic behaviour, storing complex\nhierarchies and lists of related entities.\n\nHowever, the main limitation of JSONField in Django is that it does not offer a good way of managing such objects in\nthe default admin UI. Defining JSON objects inside the textarea is not practical for most use cases. django-reactive\ntries to address this problem by offering an integration between JSONField and the awesome\n`react-jsonschema-form <https://github.com/mozilla-services/react-jsonschema-form>`_ (RJSF) JavaScript library.\nIt also uses Python `jsonschema <https://github.com/Julian/jsonschema>` library for backend validation. Such integration\nfrom our practice can significantly reduce an amount of work you need to do to build custom forms for JSONField types.\n\nIn most cases developers would only need to define a JSON schema configuration for such field and optionally UI schema\nto modify UI for those forms.\n\nA basic use case is demonstrated below:\n\n.. code-block:: python\n\n    from django.db import models\n\n    from django_reactive.fields import ReactJSONSchemaField\n\n\n    class Registration(models.Model):\n        basic = ReactJSONSchemaField(\n            help_text="Registration form",\n            schema={\n                "title": "Register now!",\n                "description": "Fill out the form to register.",\n                "type": "object",\n                "required": [\n                    "firstName",\n                    "lastName"\n                ],\n                "properties": {\n                    "firstName": {\n                        "type": "string",\n                        "title": "First name"\n                    },\n                    "lastName": {\n                        "type": "string",\n                        "title": "Last name"\n                    },\n                    "age": {\n                        "type": "integer",\n                        "title": "Age"\n                    },\n                    "bio": {\n                        "type": "string",\n                        "title": "Bio"\n                    },\n                    "password": {\n                        "type": "string",\n                        "title": "Password",\n                        "minLength": 3\n                    },\n                    "telephone": {\n                        "type": "string",\n                        "title": "Telephone",\n                        "minLength": 10\n                    }\n                }\n            },\n            ui_schema={\n                "firstName": {\n                    "ui:autofocus": True,\n                    "ui:emptyValue": ""\n                },\n                "age": {\n                    "ui:widget": "updown",\n                    "ui:title": "Age of person",\n                    "ui:description": "(earthian year)"\n                },\n                "bio": {\n                    "ui:widget": "textarea"\n                },\n                "password": {\n                    "ui:widget": "password",\n                    "ui:help": "Hint: Make it strong!"\n                },\n                "date": {\n                    "ui:widget": "alt-datetime"\n                },\n                "telephone": {\n                    "ui:options": {\n                        "inputType": "tel"\n                    }\n                }\n            },\n        )\n\nIt will generate a form like this:\n\n.. image:: images/simple.png\n\nQuick start\n-----------\n\nInstall django-reactive::\n\n    pip install django-reactive\n\nAdd it to your `INSTALLED_APPS`:\n\n.. code-block:: python\n\n    INSTALLED_APPS = (\n        ...\n        \'django_reactive\',\n        ...\n    )\n\nRunning the example\n-------------------\n\nBuild the docker image for the Django application in `example/`:\n\n* Run `docker-compose up -d`\n\nThis will automatically create the database, run migrations, import the default superuser, and run the Django development server on `http://127.0.0.1:8000`.\n\nDjango admin example\n====================\n\n* Open http://127.0.0.1:8000/admin/ and login with username `admin` and password `test`.\n* Go to the "Test models" admin section to see the example forms.\n\nNormal Django view example\n==========================\n\n* Open http://127.0.0.1:8000/create/ to create a basic form example.\n\nYou will be redirected to the detail view of the created object after the form saves.\n\nUsage outside of Django admin\n-----------------------------\n\nTo use outside of the Django admin, the following are required in the template:\n\n* A call to the form media property using {{ form.media }}\n\n* An HTML submit input with `name="_save"`.\n\n.. code-block:: html\n\n    <!DOCTYPE html>\n    <html>\n    <head>\n      <title>Homepage</title>\n    </head>\n    <body>\n      {{ form.media }}\n      <form method="post">\n        {% csrf_token %}\n        {{ form }}\n        <input type="submit" value="Save" name="_save">\n      </form>\n    </body>\n    </html>\n\nOptional configuration\n----------------------\n\nSchema fields accept the following parameters for additional configuration:\n\n* ``extra_css``: Include additional static CSS files available in the widget.\n* ``extra_js``: Include additional static JavaScript files available in the widget.\n* ``on_render``: A python method to make dynamic schema modifications at render-time.\n\nExtra CSS and JSS files should be accessible using Django\'s staticfiles configurations and passed as a list of strings.\n\nRender methods require both ``schema`` and ``ui_schema`` as arguments to allow dynamic schema modification when rendering the widget. An optional ``instance`` keyword argument may also be used for referencing an object instance (must be set on the widget in the form). This method does not return anything.\n\nExample usage\n=============\n\nThe example below demonstrates a use-case in which the options available for a particular field may be dynamic and unavailable in the initial schema definition. These would be populated at render-time and made available in the form UI.\n\n.. code-block:: python\n\n    def set_task_types(schema, ui_schema):\n        from todos.models import TaskType\n\n        task_types = list(TaskType.objects.all().values_list("name", flat=True))\n        schema["definitions"]["Task"]["properties"]["task_type"]["enum"] = task_types\n        ui_schema["task_lists"]["items"]["tasks"]["items"]["task_type"][\n            "ui:help"\n        ] = f"Select 1 of {len(task_types)} task types"\n\n    class Todo(models.Model):\n        """\n        A collection of task lists for a todo.\n        """\n\n        name = models.CharField(max_length=255)\n        task_lists = ReactJSONSchemaField(\n            help_text="Task lists",\n            schema=TODO_SCHEMA,\n            ui_schema=TODO_UI_SCHEMA,\n            on_render=set_task_types,\n            extra_css=["css/extra.css"],\n            extra_js=["js/extra.js"],\n        )\n\nSchema model form class\n=======================\n\nThe form class ``ReactJSONSchemaModelForm`` (subclassed from Django\'s ``ModelForm``) can be used to provide the model form\'s instance object to the schema field widgets:\n\n.. code-block:: python\n\n    from django_reactive.forms import ReactJSONSchemaModelForm\n    class MyModelForm(ReactJSONSchemaModelForm):\n        ...\n\nThis allows the ``on_render`` method set for a schema field to reference the instance like this:\n\n.. code-block:: python\n\n    def update_the_schema(schema, ui_schema, instance=None):\n        if instance and instance.some_condition:\n            ui_schema["my_schema_prop"]["ui:help"] = "Some extra help text"\n\nFeatures\n--------\n\n* React, RJSF and other JS assets are bundled with the package.\n* Integration with default Django admin theme.\n* Backend and frontend validation.\n* Configurable static media assets\n* Dynamic schema mutation in widget renders\n\nLimitations\n-----------\n\n* `Additional properties <https://github.com/mozilla-services/react-jsonschema-form#expandable-option>`_ ( a feature of RJSF) is not supported.\n\nTo implement this behaviour you can define an array schema with one property serving as a key of the object and do\ntransformation in your JSON class. An example will be provided later.\n\nFuture development\n------------------\n\n* Display description as tooltips\n* Polish styles and HTML generated by **RJSF**\n',
    'author': 'Artem Kolesnikov',
    'author_email': 'tyomo4ka@gmail.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/tyomo4ka/django-reactive',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.7,<4',
}


setup(**setup_kwargs)
