# -*- 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,<5.0',
 'pytest>=6.1.2,<7.0.0']

setup_kwargs = {
    'name': 'django-reactive',
    'version': '0.0.10',
    '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. In most cases\nit leads to a simpler database design.\n\nThe `JSONField <https://docs.djangoproject.com/en/3.1/ref/contrib/postgres/fields/#jsonfield>`_ in Django provides a\nnice way of using **json** and **jsonb** Postgres types in the model classes. ORM can even allow you to perform queries\nagainst the data stored inside the JSON structure. Moreover, it is possible to use\n`GIN indexes <https://www.postgresql.org/docs/12/datatype-json.html#JSON-INDEXING>`_ with **jsonb** types in Postgres, what\nmakes it a useful tool in the application design and opens a wide range of possibilities such as polymorphic behaviour,\nstoring complex hierarchies and lists of related entities, etc.\n\nHowever, the main limitation of JSONField in Django is a lack of good support of UI for JSON structures as defining JSON objects\ninside the textarea inputs is not practical for most use cases. django-reactive tries to address this problem by offering an\nintegration between JSONField and the awesome `react-jsonschema-form <https://github.com/mozilla-services/react-jsonschema-form>`_\n(RJSF) JavaScript library.\n\ndjango-reactive also uses Python `jsonschema <https://github.com/Julian/jsonschema>` library for backend validation. Such integration\ncan significantly reduce the amount of work you need to contribute into building custom forms for JSONField types.\n\nIn most cases it only requires a JSON schema configuration for such field and optionally a UI schema\nto modify some representation parameters.\n\nA basic example of this 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)
