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

packages = \
['drf_react_template']

package_data = \
{'': ['*']}

install_requires = \
['djangorestframework>=3.12.0,<4.0.0']

setup_kwargs = {
    'name': 'drf-react-template-framework',
    'version': '0.0.16',
    'description': 'Django REST Framework plugin that creates form schemas for react-jsonschema-form',
    'long_description': '# Django Rest Framework React Template Framework\nDjango Rest Framework React Template Framework is a Python package that plugs into [Django Rest Framework](https://www.django-rest-framework.org/) to generate json schemas for [react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form). The concept is similar to the DRF [HTMLFormRenderer](https://www.django-rest-framework.org/api-guide/renderers/#htmlformrenderer), but specifically designed for [React](https://reactjs.org/) frontends.\n\n## Installation\n```\npip install drf-react-template-framework\n```\n\n## Quick Start\n\nSee `/example` for a complete simple example.\n\n\n`serializers.py`:\n```python\nfrom rest_framework import serializers\n\nclass ChoiceSerializer(serializers.ModelSerializer):\n    choice_text = serializers.CharField()\n    votes = serializers.IntegerField()\n\n    class Meta:\n        fields = (\'choice_text\', \'votes\')\n```\n`viewsets.py`:\n```python\nfrom rest_framework.mixins import RetrieveModelMixin\nfrom drf_react_template.mixins import FormSchemaViewSetMixin\n\nclass ChoiceViewSet(\n    RetrieveModelMixin,\n    FormSchemaViewSetMixin,\n):\n    queryset = models.Choice.objects.all()\n    serializer_class = serializers.ChoiceSerializer\n```\nNow when the retrieve endpoint is called, `FormSchemaViewSetMixin` will update the response\nto include a `serializer` object in the json, while the original payload is sorted in `formData`.\n\nInside the `serializer` object, two fields `schema` and `uiSchema` contain the objects which\ncan be used inside [`react-jsonschema-form`](https://react-jsonschema-form.readthedocs.io/en/latest/#usage).\n\n## Documentation\n\nWhile the above quick start is useful for super simple cases,\nthe framework has a large number of additional parameters which can be used to customize behaviour.\n\n### Viewset\n\nAll viewsets must inherit from `drf_react_template.mixins.FormSchemaViewSetMixin`.\nThis class inherits from the\nDRF [`GenericViewSet`](https://www.django-rest-framework.org/api-guide/viewsets/#genericviewset),\nwhile additionally providing custom `finialize response functionality` and the additional endpoint:\n```\nGET */create/\n>> {\'serializer\': ..., \'formData\': {}}\n```\nWhich can be used to generate an empty form for create.\n\nThe only other specific customization that can be applied in the viewset is different\nserializers for different endpoints. For example, `update` actions often show a subset of fields;\nas such it is possible to override `get_serializer_class` to return the specific form required.\n\nFor example:\n```python\n# serializers.py\nclass ChoiceSerializer(serializers.ModelSerializer):\n    choice_text = serializers.CharField()\n    votes = serializers.IntegerField()\n\n    class Meta:\n        fields = (\'choice_text\', \'votes\')\n\nclass ChoiceUpdateSerializer(serializers.ModelSerializer):\n    choice_text = serializers.CharField()\n\n    class Meta:\n        fields = (\'choice_text\',)\n\n# viewsets.py\ndef get_serializer_class(self):\n    if self.action == \'update\':\n        return ChoiceUpdateSerializer\n    return ChoiceSerializer\n```\n\nSince this having a separate `list` serializer is so common, the above can be avoided by using\nthe `serializer_list_class` class attribute provided by `FormSchemaViewSetMixin`.\n\n### Serializer\n\nThe majority of the customization will occur inside serializer classes;\na real world example will often require custom `create`, `update`, `to_representation`, etc methods.\n\nAt the class level the serializer defines the form name:\n```\nChoiceSerializer -> Choice\nQuestionAndChoiceSerializer -> Question And Choice\nChoice -> Choice\n```\nIf a different title is required (or no title for nested forms), then the `__init__` method can be updated:\n```python\ndef __init__(self, *args, **kwargs):\n    kwargs[\'label\'] = \'New Form Title\'\n    super().__init__(*args, **kwargs)\n```\n\n#### Serializer Field Attributes\n\nThe following is a list of parameters that can be added to individual fields which modifies\n`react-jsonschema-form` functionality on the front-end.\n\n##### Label\nUpdates the form input title text. Can also be used to provide translations.\n```python\nchoice_text = serializers.CharField(label=\'What is the choice label?\')\n```\nThe label can also be disabled completely via `style`:\n```python\nchoice_text = serializers.CharField(style={\'ui:options\': {\'label\': False}})\n```\nNote: This does not work for `list` actions.\n\n##### Read Only\nSetting `read_only=True` forces the encoder to skip it when building the form,\nbut still means the value gets sent in the `formData`:\n```python\nchoice_text = serializers.CharField(read_only=True)\n```\nThis is useful for custom widgets which rely on data not related to the form (e.g. `id`).\n\n##### Required\nSetting `required=False` removes frontend validation of the field:\n```python\nchoice_text = serializers.CharField(required=False)\n```\nNote: This has no effect on `list` actions.\n\n##### Allow Null\nSetting `allow_null=True` allows `null` values to be sent back in `formData`:\n```python\nchoice_text = serializers.CharField(allow_null=True)\n```\nNote: This has no effect on `list` actions.\n\n##### Default\nBy setting a default value, a field is automatically set to `required=False`.\nThe `formData` object will also contain the `default` value if it is not provided one.\n```python\nchoice_text = serializers.CharField(default=\'example text\')\n```\nNote: This has no effect on `list` actions.\n\n##### Validation Mapping\nBuilt-in validators are automatically added to the schema. For instance:\n```python\nchar_text = serializers.CharField(min_length=5, max_length=10)\n```\n\nWill result in the following schema portion:\n\n```json\n{\n    "type": "string",\n    "title": "Char text",\n    "maxLength": 10,\n    "minLength": 5\n}\n```\n\nThe following core validators have mapping to json schema (https://ajv.js.org/json-schema.html):\n\n- MaxLengthValidator: maxLength\n- MinLengthValidator: minLength\n- MaxValueValidator: maximum\n- MinValueValidator: minimum\n- RegexValidator: pattern\n\nCustom validators can not be mapped directly to Ajv schema properies so they are rather provided in the json ui schema as hints.\n\n```python\nclass MinSizeImageValidator:\n    message = _(\'Image is too small, must be 1KB minimum.\')\n    code = \'image_min_1KB\'\n\n    def __call__(self, value):\n        min_size = 1024  # 1KB\n        if value.size < min_size:\n            raise serializers.ValidationError(self.message, code=self.code)\n\nimage_field = serializers.ImageField(\n    required=True, validators=[MinSizeImageValidator]\n)\n```\n\nWill result in the following ui schema portion:\n\n```json\n{\n    "ui:widget": "file",\n    "ui:custom-validators": [\n        {"code": "image_min_1KB", "message": "Image is too small, must be 1KB minimum."}\n    ]\n}\n```\n\n##### Style\nThe DRF `style` parameter is a `dict` and is therefore used for a number of different parameters.\nThere are a [number of options](https://react-jsonschema-form.readthedocs.io/en/latest/api-reference/uiSchema/)\nthat `react-jsonschema-form` provides, many of which should work out-of-the-box,\nalthough not all options will have been tested.\n\nSince style params are applied **last**, they can overwrite other keys. Additionally, any key not\nstarting with `schema:` will be sent in the `json` payload, so this can be a good place to send\nadditional attributes for custom widgets.\n\nThe following are a list of valid (tested) keys and their uses.\n\n**Note**: This can also be done at the serializer level:\n```python\ndef __init__(self, *args, **kwargs):\n    kwargs[\'style\'] = {\'ui:template\': \'Card\'}\n    super().__init__(*args, **kwargs)\n```\n\n###### Dependencies\n\n`react-jsonschema-form` allows for the use of [dependencies](https://react-jsonschema-form.readthedocs.io/en/latest/usage/dependencies/#dependencies)\nbetween multiple fields. This library has analogues for the four types (bidirectional, unidirectional, conditional, and\ndynamic).\n```python\n# Unidirectional\nchoice_text = serializers.CharField(\n    style={\'schema:dependencies:simple\': [\'votes\']}\n)\n\n# Bidirectional - note the different value styles, either is fine.\nchoice_text = serializers.CharField(\n    style={\'schema:dependencies:simple\': [\'votes\']}\n)\nvotes = serializers.IntegerField(\n    default=0, style={\'schema:dependencies:simple\': \'choice_text\'}\n)\n\n# Conditional\nchoice_text = serializers.CharField(\n    style={\'schema:dependencies:conditional\': [\'votes\']}\n)\n\n# Dynamic - must be an enum field, and only one choice per dependency,\n# multiple choices can have the same dependencies (side-stepping this issue).\nchoice_text = serializers.ChoiceField(\n    choices=((\'yes\', \'Yes\'), (\'no\', \'No\')),\n    style={\'schema:dependencies:dynamic\': {\'yes\': [\'votes\'], \'no\': None}}\n)\n```\n\n###### Field Overrides\n\nSince this framework doesn\'t cover 100% of the features of the `react-jsonschema-form`, it is possible to provide\n`dict` objects which override the individual field properties:\n```python\nchoice_text = serializers.CharField(\n    style={\n        \'schema:override\': {\'type\': \'string\', \'title\': \'Overridden title\'},\n        \'uiSchema:override\': {\'ui:widget\': \'updown\'},\n        \'column:override\': {\n            \'title\': \'Overridden title\',\n            \'dataIndex\': \'question_text\',\n            \'key\': \'question_text\',\n        },\n        \'schema:dependencies:override\': [\'votes\']\n    }\n)\n```\n**Note**: There is no validation around these overrides, so it is left up to the developer to ensure the resulting\nschema is valid. For example, `\'schema:dependencies:override\'` will not remove fields from the main `\'properties\'` or\n`\'required\'` objects. (This can be done by omitting the dependant field from the serializer or using `read_only=True`).\n\n###### List Sort Order\nSends the `defaultSortOrder` key with the `list` action serializer:\n```python\nchoice_text = serializers.CharField(, style={\'schema:sort\': \'ascend\'})\n```\n\n###### Widget, Type, and Enum\nWhile the framework tries to provide sensible defaults for DRF fields,\nsometimes custom frontend widgets need to provide custom behaviour.\n```python\nchoice_text = serializers.CharField(style={\n    \'ui:widget\': \'textarea\',\n    \'schema:type\': \'string\',\n    \'schema:enum\': \'choices\'\n})\n```\nMore information can be found on\n[`types`](https://react-jsonschema-form.readthedocs.io/en/latest/usage/single/#field-types)\nand [`enum`](https://react-jsonschema-form.readthedocs.io/en/latest/usage/single/#enumerated-values).\n\n`enum` can also be set to the `string` `choices` (as in the example),\nto try and use the `field.choices` attribute.\n\n###### Placeholder\nThe HTML placeholder text can be updated in the following way:\n```python\nchoice_text = serializers.CharField(style={\'ui:placeholder\': \'This a placeholder value\'})\n```\n\n###### Text Area Widget Rows\nWhen the `ui:widget` is set to `textarea` (see above), the `rows` can be set via:\n```python\nchoice_text = serializers.CharField(style={\n    \'ui:widget\': \'textarea\',\n    \'ui:options\': {\'rows\': 8},\n})\n```\n\n###### Disabled\nAn input field can be `disabled` in the following way:\n```python\nchoice_text = serializers.CharField(style={\'ui:disabled\': \'true\'})\n```\n\n### Settings\n\n##### DRF_REACT_TEMPLATE_TYPE_MAP\nAllows for custom fields to be added to `ProcessingMixin.TYPE_MAP` in this way:\n```python\nDRF_REACT_TEMPLATE_TYPE_MAP = {\n    \'ImageField\': {\'type\': \'image\', \'widget\': \'file\'},\n}\n```\nThe default supported field types are:\n\n```python\n{\n    \'CharField\': {\'type\': \'string\'},\n    \'IntegerField\': {\'type\': \'integer\', \'widget\': \'updown\'},\n    \'FloatField\': {\'type\': \'number\', \'widget\': \'updown\'},\n    \'DecimalField\': {\'type\': \'number\', \'widget\': \'updown\'},\n    \'BooleanField\': {\'type\': \'boolean\'},\n    \'DateTimeField\': {\'type\': \'string\', \'widget\': \'date-time\'},\n    \'DateField\': {\'type\': \'string\', \'widget\': \'date\'},\n    \'URLField\': {\'type\': \'string\', \'widget\': \'uri\'},\n    \'ChoiceField\': {\'type\': \'string\', \'enum\': \'choices\'},\n    \'EmailField\': {\'type\': \'string\', \'widget\': \'email\'},\n    \'ListField\': {\'type\': \'array\'},\n}\n```\n\n## Development\n\nThis Repo uses [Poetry](https://python-poetry.org/docs/),\nand setup for development is as simple as follows:\n```bash\npoetry init\npre-commit install\n```\n',
    'author': 'stuart.bradley',
    'author_email': 'stuy.bradley@gmail.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/yoyowallet/drf-react-template-framework',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.7,<4.0',
}


setup(**setup_kwargs)
