{"id":17780742,"url":"https://github.com/sibyx/django_api_forms","last_synced_at":"2025-10-29T18:31:16.092Z","repository":{"id":39579798,"uuid":"216655247","full_name":"Sibyx/django_api_forms","owner":"Sibyx","description":"Declarative Django request validation for RESTful APIs","archived":false,"fork":false,"pushed_at":"2024-08-16T00:09:25.000Z","size":1042,"stargazers_count":22,"open_issues_count":9,"forks_count":13,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-02-06T22:11:19.777Z","etag":null,"topics":["django","django-forms","django-validators","hacktoberfest","http","json","rest"],"latest_commit_sha":null,"homepage":"https://sibyx.github.io/django_api_forms/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Sibyx.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-10-21T20:04:21.000Z","updated_at":"2024-10-27T14:40:42.000Z","dependencies_parsed_at":"2024-12-17T10:05:20.882Z","dependency_job_id":"f093a02d-3650-4182-a6f1-94fccaf56430","html_url":"https://github.com/Sibyx/django_api_forms","commit_stats":{"total_commits":188,"total_committers":11,"mean_commits":17.09090909090909,"dds":"0.17553191489361697","last_synced_commit":"508f3bea0b59de6c4704e02efc9f463b6031dbd0"},"previous_names":[],"tags_count":54,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sibyx%2Fdjango_api_forms","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sibyx%2Fdjango_api_forms/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sibyx%2Fdjango_api_forms/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sibyx%2Fdjango_api_forms/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Sibyx","download_url":"https://codeload.github.com/Sibyx/django_api_forms/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238869862,"owners_count":19544429,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["django","django-forms","django-validators","hacktoberfest","http","json","rest"],"created_at":"2024-10-27T03:03:46.718Z","updated_at":"2025-10-29T18:31:16.087Z","avatar_url":"https://github.com/Sibyx.png","language":"Python","readme":"# Django API Forms\n\n[![PyPI version](https://badge.fury.io/py/django-api-forms.svg)](https://badge.fury.io/py/django-api-forms)\n[![codecov](https://codecov.io/gh/Sibyx/django_api_forms/branch/master/graph/badge.svg)](https://codecov.io/gh/Sibyx/django_api_forms)\n\n**Django API Forms** is a Python library that brings the [Django Forms](https://docs.djangoproject.com/en/4.1/topics/forms/) approach to processing RESTful HTTP request payloads (such as [JSON](https://www.json.org/) or [MessagePack](https://msgpack.org/)) without the HTML front-end overhead.\n\n## Overview\n\nDjango API Forms provides a declarative way to:\n\n- Define request validation schemas using a familiar Django-like syntax\n- Parse and validate incoming API requests\n- Handle nested data structures and complex validation rules\n- Convert validated data into Python objects\n- Populate Django models or other objects with validated data\n\n[**📚 Read the full documentation**](https://sibyx.github.io/django_api_forms/)\n\n## Key Features\n\n- **Declarative Form Definition**: Define your API request schemas using a familiar Django Forms-like syntax\n- **Request Validation**: Validate incoming requests against your defined schemas\n- **Nested Data Structures**: Handle complex nested JSON objects and arrays\n- **Custom Field Types**: Specialized fields for common API use cases (BooleanField, EnumField, etc.)\n- **File Uploads**: Support for BASE64-encoded file and image uploads\n- **Object Population**: Easily populate Django models or other objects with validated data\n- **Customizable Validation**: Define custom validation rules at the field or form level\n- **Multiple Content Types**: Support for JSON, MessagePack, and extensible to other formats\n\n## Motivation\n\nThe main idea was to create a simple and declarative way to specify the format of expected requests with the ability\nto validate them. Firstly, I tried to use [Django Forms](https://docs.djangoproject.com/en/4.1/topics/forms/) to\nvalidate my API requests (I use pure Django in my APIs). I encountered a problem with nesting my requests without\na huge boilerplate. Also, the whole HTML thing was pretty useless in my RESTful APIs.\n\nI wanted to:\n\n- Define my requests as objects (`Form`)\n- Pass the request to my defined object (`form = Form.create_from_request(request, param=param))`)\n  - With the ability to pass any extra optional arguments\n- Validate my request (`form.is_valid()`)\n- Extract data (`form.cleaned_data` property)\n\nI wanted to keep:\n\n- Friendly declarative Django syntax\n  ([DeclarativeFieldsMetaclass](https://github.com/django/django/blob/master/django/forms/forms.py#L22) is beautiful)\n- [Validators](https://docs.djangoproject.com/en/4.1/ref/validators/)\n- [ValidationError](https://docs.djangoproject.com/en/4.1/ref/exceptions/#validationerror)\n- [Form fields](https://docs.djangoproject.com/en/4.1/ref/forms/fields/) (In the end, I had to \"replace\" some of them)\n\nSo I created this Python package to cover all these expectations.\n\n## Installation\n\n```shell\n# Using pip\npip install django-api-forms\n\n# Using poetry\npoetry add django-api-forms\n\n# Local installation from source\npython -m pip install .\n```\n\n### Requirements\n\n- Python 3.9+\n- Django 2.0+\n\n### Optional Dependencies\n\nDjango API Forms supports additional functionality through optional dependencies:\n\n```shell\n# MessagePack support (for Content-Type: application/x-msgpack)\npip install django-api-forms[msgpack]\n\n# File and Image Fields support\npip install django-api-forms[Pillow]\n\n# RRule Field support\npip install django-api-forms[rrule]\n\n# GeoJSON Field support\npip install django-api-forms[gdal]\n\n# Install multiple extras at once\npip install django-api-forms[Pillow,msgpack]\n```\n\nFor more detailed installation instructions, see the [Installation Guide](https://sibyx.github.io/django_api_forms/install/).\n\nInstall application in your Django project by adding `django_api_forms` to yours `INSTALLED_APPS`:\n\n```python\nINSTALLED_APPS = (\n    'django.contrib.auth',\n    'django.contrib.contenttypes',\n    'django.contrib.sessions',\n    'django.contrib.messages',\n    'django_api_forms'\n)\n```\n\nYou can change the default behavior of population strategies or parsers using these settings (listed with default\nvalues). Keep in mind, that dictionaries are not replaced by your settings they are merged with defaults.\n\nFor more information about the parsers and the population strategies check the documentation.\n\n```python\nDJANGO_API_FORMS_POPULATION_STRATEGIES = {\n    'django_api_forms.fields.FormFieldList': 'django_api_forms.population_strategies.IgnoreStrategy',\n    'django_api_forms.fields.FileField': 'django_api_forms.population_strategies.IgnoreStrategy',\n    'django_api_forms.fields.ImageField': 'django_api_forms.population_strategies.IgnoreStrategy',\n    'django_api_forms.fields.FormField': 'django_api_forms.population_strategies.IgnoreStrategy',\n    'django.forms.models.ModelMultipleChoiceField': 'django_api_forms.population_strategies.IgnoreStrategy',\n    'django.forms.models.ModelChoiceField': 'django_api_forms.population_strategies.ModelChoiceFieldStrategy'\n}\n\nDJANGO_API_FORMS_DEFAULT_POPULATION_STRATEGY = 'django_api_forms.population_strategies.BaseStrategy'\n\nDJANGO_API_FORMS_PARSERS = {\n    'application/json': 'json.loads',\n    'application/x-msgpack': 'msgpack.loads'\n}\n```\n\n## Quick Example\n\nHere's a simple example demonstrating how to use Django API Forms:\n\n```python\nfrom django.forms import fields\nfrom django.http import JsonResponse\nfrom django_api_forms import Form, FormField, FieldList\n\n# Define a nested form\nclass ArtistForm(Form):\n    name = fields.CharField(required=True, max_length=100)\n    genres = FieldList(field=fields.CharField(max_length=30))\n    members = fields.IntegerField()\n\n# Define the main form\nclass AlbumForm(Form):\n    title = fields.CharField(max_length=100)\n    year = fields.IntegerField()\n    artist = FormField(form=ArtistForm)\n\n# In your view\ndef create_album(request):\n    form = AlbumForm.create_from_request(request)\n    if not form.is_valid():\n        # Handle validation errors\n        return JsonResponse({\"errors\": form.errors}, status=400)\n\n    # Access validated data\n    album_data = form.cleaned_data\n    # Do something with the data...\n\n    return JsonResponse({\"status\": \"success\"})\n```\n\nThis form can validate a JSON request like:\n\n```json\n{\n  \"title\": \"Unknown Pleasures\",\n  \"year\": 1979,\n  \"artist\": {\n    \"name\": \"Joy Division\",\n    \"genres\": [\"rock\", \"punk\"],\n    \"members\": 4\n  }\n}\n```\n\n### More Examples\n\nFor more comprehensive examples, check out the documentation:\n\n- [Basic Example with Nested Data](https://sibyx.github.io/django_api_forms/example/#basic-example-music-album-api)\n- [User Registration with File Upload](https://sibyx.github.io/django_api_forms/example/#example-user-registration-with-file-upload)\n- [API with Django Models](https://sibyx.github.io/django_api_forms/example/#example-api-with-django-models)\n- [ModelChoiceField Example](https://github.com/pawl/django_api_forms_modelchoicefield_example) - External repository by [pawl](https://github.com/pawl)\n\n## Documentation\n\nComprehensive documentation is available at [https://sibyx.github.io/django_api_forms/](https://sibyx.github.io/django_api_forms/)\n\nThe documentation includes:\n\n- [Installation Guide](https://sibyx.github.io/django_api_forms/install/)\n- [Tutorial](https://sibyx.github.io/django_api_forms/tutorial/)\n- [Field Reference](https://sibyx.github.io/django_api_forms/fields/)\n- [Examples](https://sibyx.github.io/django_api_forms/example/)\n- [API Reference](https://sibyx.github.io/django_api_forms/api_reference/)\n- [Contributing Guide](https://sibyx.github.io/django_api_forms/contributing/)\n\n## Running Tests\n\n```shell\n# Install all dependencies\npoetry install\n\n# Run code-style check\npoetry run flake8 .\n\n# Run the tests\npoetry run python runtests.py\n\n# Run tests with coverage\npoetry run coverage run runtests.py\npoetry run coverage report\n```\n\n## License\n\nDjango API Forms is released under the MIT License.\n\n---\nMade with ❤️ and ☕️ by Jakub Dubec, [BACKBONE s.r.o.](https://www.backbone.sk/en/) \u0026\n[contributors](https://github.com/Sibyx/django_api_forms/graphs/contributors).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsibyx%2Fdjango_api_forms","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsibyx%2Fdjango_api_forms","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsibyx%2Fdjango_api_forms/lists"}