Skip to main content

Django API Forms

PyPI version

Django Forms approach in validation of request payload (especially for content type like JSON or MessagePack) without HTML front-end.

WIP: Library API is pretty unstable!

Motivation

Main idea was to create a simple and declarative way to specify format of expecting request with ability to validate them. Firstly I tried to use Django Forms to validate my API request (I use pure Django in my APIs). I have encountered a problem with nesting my requests without huge boilerplate. Also, the whole HTML thing was pretty useless in my RESTful APIs.

I wanted something to:

  • define my requests as object (Form)
  • pass the request to my defined object (form = Form.create_from_request(request))
  • validate my request form.is_valid()
  • extract data form.clean_data property

I wanted to keep:

So I decided to create simple Python package to cover all my expectations.

Installation

# Using pip
pip install django_api_forms

# Using pipenv
pipenv install django_api_forms

# Using setup.py
python setup.py install

Example

Simple nested JSON request

{
  "title": "Unknown Pleasures",
  "type": "vinyl",
  "artist": {
    "name": "Joy Division",
    "genres": [
      "rock",
      "punk"
    ],
    "members": 4
  },
  "year": 1979,
  "songs": [
    {
      "title": "Disorder",
      "duration": "3:29"
    },
    {
      "title": "Day of the Lords",
      "duration": "4:48",
      "metadata": {
        "_section": {
          "type": "ID3v2",
          "offset": 0,
          "byteLength": 2048
        },
        "header": {
          "majorVersion": 3,
          "minorRevision": 0,
          "flagsOctet": 0,
          "unsynchronisationFlag": false,
          "extendedHeaderFlag": false,
          "experimentalIndicatorFlag": false,
          "size": 2038
        }
      }
    }
  ],
  "metadata": {
    "created_at": "2019-10-21T18:57:03+0100",
    "updated_at": "2019-10-21T18:57:03+0100"
  }
}

Django API Forms equivalent + validation

from enum import Enum

from django.core.exceptions import ValidationError
from django.forms import fields

from django_api_forms import FieldList, FormField, FormFieldList, DictionaryField, EnumField, AnyField, Form


class AlbumType(Enum):
    CD = 'cd'
    VINYL = 'vinyl'


class ArtistForm(Form):
    name = fields.CharField(required=True, max_length=100)
    genres = FieldList(field=fields.CharField(max_length=30))
    members = fields.IntegerField()


class SongForm(Form):
    title = fields.CharField(required=True, max_length=100)
    duration = fields.DurationField(required=False)
    metadata = AnyField(required=False)


class AlbumForm(Form):
    title = fields.CharField(max_length=100)
    year = fields.IntegerField()
    artist = FormField(form=ArtistForm)
    songs = FormFieldList(form=SongForm)
    type = EnumField(enum=AlbumType, required=True)
    metadata = DictionaryField(fields.DateTimeField())

    def clean_year(self):
        if self.cleaned_data['year'] == 1992:
            raise ValidationError("Year 1992 is forbidden!", 'forbidden-value')
        return self.cleaned_data['year']

    def clean(self):
        if (self.cleaned_data['year'] == 1998) and (self.cleaned_data['artist']['name'] == "Nirvana"):
            raise ValidationError("Sounds like a bullshit", code='time-traveling')
        return self.cleaned_data



"""
Django view example
"""
def create_album(request):
    form = AlbumForm.create_from_request(request)
    if not form.is_valid():
        # Process your validation error
        print(form.errors)

    # Cleaned valid payload
    payload = form.cleaned_data
    print(payload)

Made with ❤️ and ☕️ by Jakub Dubec & BACKBONE s.r.o.

Changelog

0.7.0 : 03.02.2020

  • Change: Library renamed from django_request_formatter to django_api_forms
  • Change: Imports in main module django_api_forms

0.6.0 : 18.02.2020

  • Feature: BooleanField introduced

0.5.8 : 07.01.2020

  • Fix: Pass Invalid value as ValidationError not as a string

0.5.7 : 07.01.2020

  • Fix: Introduced generic Invalid value error message, if there is AttributeError, TypeError, ValueError

0.5.6 : 01.01.2020

  • Fix: Fixing issue from version 0.5.5 but this time for real
  • Change: Renamed version file from __version__.py to version.py

0.5.5 : 01.01.2020

  • Fix: Check instance only if there is a value in FieldList and FormFieldList

0.5.4 : 24.12.2019

  • Fix: Added missing msgpack`` dependency to setup.py`

0.5.3 : 20.12.2019

  • Feature: Introduced generic AnyField

0.5.2 : 19.12.2019

  • Fix: Skip processing of the FormField if value is not required and empty

0.5.1 : 19.12.2019

  • Fix: Process EnumField even if it's not marked as required

0.5.0 : 16.12.2019

  • Change: Use native django.form.fields if possible
  • Change: Removed kwargs propagation from release 0.3.0
  • Change: Changed syntax back to django.forms compatible (e.g. form.validate_{key}() -> form.clean_{key}())
  • Change: FieldList raises ValidationError instead of RuntimeException if there is a type in validation
  • Change: Use private properties for internal data in field objects
  • Fixed: FieldList returns values instead of None
  • Fix: Fixed validation in DictionaryField
  • Maintenance: Basic unit tests

0.4.3 : 29.11.2019

  • Fix: Fixed Form has no attribute self._data

0.4.2 : 29.11.2019

  • Fix: If payload is empty, create empty dictionary to avoid NoneType error

0.4.1 : 14.11.2019

  • Feature: Introduced UUIDField

0.4.0 : 13.11.2019

  • Feature: Introduced DictionaryField

0.3.0 : 11.11.2019

  • Feature: Propagate kwargs from Form.is_valid() to Form.validate() and Form.validate_{key}() methods

0.2.1 : 4.11.2019

  • Fix: Fixed to_python() in FormFieldList

0.2.0 : 31.10.2019

  • Change: Form.validate() replaced by Form.is_valid()
  • Feature: Form.validate() is now used as a last step of form validation and it's aimed to be overwritten if needed
  • Note: Unit tests initialization

0.1.6 : 24.10.2019

  • Fix: Non-required EnumField is now working
  • Feature: WIP: Initial method for filling objects Form::fill()

0.1.5 : 23.10.2019

  • Fix: Assign errors to form before raising ValidationError

0.1.4 : 23.10.2019

  • Fix: Do not return empty error records in Form:errors

0.1.3 : 23.10.2019

  • Fix: Use custom DeclarativeFieldsMetaclass because of custom Field class
  • Fix: Do not return untouched fields in Form::payload
  • Fix: Fix for None default_validators in Field

0.1.2 : 22:10.2019

  • Feature: Support for validation_{field} methods in Form (initial support)

0.1.1 : 22.10.2019

  • Feature: EnumField

0.1.0 : 22.10.2019

  • Feature: First version of Form class
  • Feature: CharField
  • Feature: IntegerField
  • Feature: FloatField
  • Feature: DecimalField
  • Feature: DateField
  • Feature: TimeField
  • Feature: DateTimeField
  • Feature: DurationField
  • Feature: RegexField
  • Feature: EmailField
  • Feature: BooleanField
  • Feature: RegexField
  • Feature: FieldList
  • Feature: FormField
  • Feature: FormFieldList

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_api_forms-0.7.0.tar.gz (10.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_api_forms-0.7.0-py3-none-any.whl (9.5 kB view details)

Uploaded Python 3

File details

Details for the file django_api_forms-0.7.0.tar.gz.

File metadata

  • Download URL: django_api_forms-0.7.0.tar.gz
  • Upload date:
  • Size: 10.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.8.1

File hashes

Hashes for django_api_forms-0.7.0.tar.gz
Algorithm Hash digest
SHA256 99b47533aa8e798388a7a75c4a290f17dd14a3bf0db8c67e75e6a797bbd6beda
MD5 9f0533a8a358325dcd0898074054c781
BLAKE2b-256 340dc351922e28e6cfddcac2c20fc0ca602aa1a3e70b5e3113806632f20f3bba

See more details on using hashes here.

File details

Details for the file django_api_forms-0.7.0-py3-none-any.whl.

File metadata

  • Download URL: django_api_forms-0.7.0-py3-none-any.whl
  • Upload date:
  • Size: 9.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.8.1

File hashes

Hashes for django_api_forms-0.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fea37d81b716d4db53170cfcca5b938588cb89b4f924d1fdaa244de21a47b519
MD5 74c2dd3e23bb3933ef14d1f065deef4e
BLAKE2b-256 dcf94cf81fb5b320a9d8467af8d8d6a29873655c1937860a4ae39cc6368a4986

See more details on using hashes here.

Release history Release notifications | RSS feed

0.21.0

2 files

0.20.1

2 files

0.20.0

2 files

0.19.1

2 files

0.19.0

2 files

0.18.0

2 files

0.17.0

2 files

0.16.4

2 files

0.16.3

2 files

0.16.2

2 files

0.16.1

2 files

0.16.0

2 files

0.15.1

2 files

0.15.0

2 files

0.14.0

2 files

0.13.0

2 files

0.12.0

2 files

0.11.0

2 files

0.10.0

2 files

0.9.0

2 files

0.8.0

2 files

0.7.1

2 files

This release

0.7.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page