A platform independent django form serializer

Overview

django-remote-forms

A package that allows you to serialize django forms, including fields and widgets into Python dictionary for easy conversion into JSON and expose over API

Please go through my djangocon US 2012 talk to understand the problem sphere, motivations, challenges and implementation of Remote Forms

Sample Implementation

If you don't mind digging around a little bit to learn about different the components that might be necessary for an implementation of django-remote-forms, check out django Remote Admin django-remote-admin

Usage

Minimal Example

from django_remote_forms.forms import RemoteForm

form = LoginForm()
remote_form = RemoteForm(form)
remote_form_dict = remote_form.as_dict()

Upon converting the dictionary into JSON, it looks like this:

{
    "is_bound": false,
    "non_field_errors": [],
    "errors": {},
    "title": "LoginForm",
    "fields": {
        "username": {
            "title": "CharField",
            "required": true,
            "label": "Username",
            "initial": null,
            "help_text": "This is your django username",
            "error_messages": {
                "required": "This field is required.",
                "invalid": "Enter a valid value."
            },
            "widget": {
                "title": "TextInput",
                "is_hidden": false,
                "needs_multipart_form": false,
                "is_localized": false,
                "is_required": true,
                "attrs": {
                    "maxlength": "30"
                },
                "input_type": "text"
            },
            "min_length": 6,
            "max_length": 30
        },
        "password": {
            "title": "CharField",
            "required": true,
            "label": "Password",
            "initial": null,
            "help_text": "",
            "error_messages": {
                "required": "This field is required.",
                "invalid": "Enter a valid value."
            },
            "widget": {
                "title": "PasswordInput",
                "is_hidden": false,
                "needs_multipart_form": false,
                "is_localized": false,
                "is_required": true,
                "attrs": {
                    "maxlength": "128"
                },
                "input_type": "password"
            },
            "min_length": 6,
            "max_length": 128
        }
    },
    "label_suffix": ":",
    "prefix": null,
    "csrfmiddlewaretoken": "2M3MDgfzBmkmBrJ9U0MuYUdy8vgeCCgw",
    "data": {
        "username": null,
        "password": null
    }
}

An API endpoint serving remote forms

from django.core.serializers.json import simplejson as json, DjangoJSONEncoder
from django.http import HttpResponse
from django.middleware.csrf import CsrfViewMiddleware
from django.views.decorators.csrf import csrf_exempt

from django_remote_forms.forms import RemoteForm

from my_awesome_project.forms import MyAwesomeForm


@csrf_exempt
def my_ajax_view(request):
    csrf_middleware = CsrfViewMiddleware()

    response_data = {}
    if request.method == 'GET':
        # Get form definition
        form = MyAwesomeForm()
    elif request.raw_post_data:
        request.POST = json.loads(request.raw_post_data)
        # Process request for CSRF
        csrf_middleware.process_view(request, None, None, None)
        form_data = request.POST.get('data', {})
        form = MyAwesomeForm(form_data)
        if form.is_valid():
            form.save()

    remote_form = RemoteForm(form)
    # Errors in response_data['non_field_errors'] and response_data['errors']
    response_data.update(remote_form.as_dict())

    response = HttpResponse(
        json.dumps(response_data, cls=DjangoJSONEncoder),
        mimetype="application/json"
    )

    # Process response for CSRF
    csrf_middleware.process_response(request, response)
    return response

djangocon Proposal

This is a bit lengthy. But if you want to know more about my motivations behind developing django-remote-forms then read on.

In our quest to modularize the architecture of web applications, we create self-containing backend systems that provide web APIs for programmatic interactions. This gives us the flexibility to separate different system components. A system with multiple backend components e.g. user profile engine, content engine, community engine, analytics engine may have a single frontend application that fetches data from all of these components using respective web APIs.

With the increased availability of powerful JavaScript frameworks, such frontend applications are often purely JS based to decrease application footprint, increase deployment flexibility and separate presentation from data. The separation is very rewarding from a software engineering standpoint but imposes several limitations on system design. Using django to construct the API for arbitrary consumers comes with the limitation of not being able to utilize the powerful django form subsystem to drive forms on these consumers. But is there a way to overcome this restriction?

This is not a trivial problem to solve and there are only a few assumptions we can make about the web API consumer. It can be a native mobile or desktop - application or browser. We advocate that web APIs should provide sufficient information about 'forms' so that they can be faithfully reproduced at the consumer end.

Even in a API backend built using django, forms are essential for accepting, filtering, processing and saving data. The django form subsystem provides many useful features to accomplish these tasks. At the same time it facilitates the process of rendering the form elements in a browser environment. The concepts of form fields combined with widgets can go a long way in streamlining the interface to interact with data.

We propose an architecture to serialize information about django forms (to JSON) in a framework independent fashion so that it can be consumed by any frontend application that renders HTML. Such information includes but is not limited to basic form configurations, security tokens (if necessary), rendering metadata and error handling instructions. We lovingly name this architecture django-remote-forms.

At WiserTogether, we are in the process of building a component based architecture that strictly provides data endpoints for frontend applications to consume. We are working towards developing our frontend application for web browsers using backbone.js as MVC and handlebars as the templating engine. django-remote-forms helps us streamline our data input interface with the django forms living at the API backend.

Comments
  • ModelMultipleChoiceField with CheckBoxSelectMultiple

    ModelMultipleChoiceField with CheckBoxSelectMultiple

    If I have a form in forms.py

    class SomeForm(forms.Form): some_var = ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple,queryset=SomeModel.objects.all())

    The multiple selects are not captured when converting a filled form to a RemoteForm() object only the last select is captured

    opened by Lutando 2
  • 'RemoteTypedChoiceField' object has no attribute 'coerce'

    'RemoteTypedChoiceField' object has no attribute 'coerce'

    Just tried the example from the readme with a simple modelform with choicefield on it. After running it I got this:

    'RemoteTypedChoiceField' object has no attribute 'coerce'

    File: django_remote_forms-0.0.1-py2.7.egg/django_remote_forms/fields.py in as_dict, line 198

    I checked the source code and effectively there is no such a attribute called 'coerce'

    opened by hugotox 2
  • Changed widget titles for Email, Number and URL inputs

    Changed widget titles for Email, Number and URL inputs

    Adding these new widgets in django 1.6 breaks django-remote-form API compatibility with old JS clients. I changed all widget titles to 'TextInput', so, old JS may interpret them as usual text inputs.

    opened by bsod90 1
  • Use proper method to fetch initial field data.

    Use proper method to fetch initial field data.

    Hi there! Just noticed this small bug when using initial dictionary with the form.

    Using getattr() on initial, which is a dict, would try to fetch an attribute on that dictionary, rather than a key within it.

    opened by bartek 1
  • More widgets

    More widgets

    Added

    class RemotePasswordInput(RemoteInput):
    
    class RemoteHiddenInput(RemoteInput):
    
    class RemoteEmailInput(RemoteInput):
    

    that was added in django 1.6 and did not have corresponding classes in django-remote-forms

    opened by bsod90 0
  • Improper super() on FileField

    Improper super() on FileField

    In forms.py line 147, super() function is being called on the parent class (RemoteField), not the RemoteFileField. To work properly it should be:

    field_dict = super(RemoteFileField, self).as_dict()

    opened by smotes 0
  • Datefield and

    Datefield and "to_python"

    2 issues:

    1. In my database I have dates before 1900 so when I try to serialize a modelform I get the error about strftime can't format dates before 1900
    2. In django 1.5 and 1.6 Im getting this error from utils.py (resolve_promise method): "to_python() takes exactly 2 arguments (1 given)"

    If you want to see this is my fork where I fixed these 2 issues: https://github.com/hugotox/django-remote-forms

    opened by hugotox 0
  • Syntax error in forms.py

    Syntax error in forms.py

    I get a syntax error when importing django remote forms

    \django_remote_forms\forms.py", line 141 except Exception, e: ^ SyntaxError: invalid syntax

    Is this a problem on my end or from the package? thanks in advance

    opened by cdromart 2
  • Import issue

    Import issue

    As soon as I add this line: "from django_remote_forms.forms import RemoteForm", I get an exception error:

    File "/home/reeson/pyenv/djangoenv/lib/python3.9/site-packages/django_remote_forms/forms.py", line 141 except Exception, e: ^ SyntaxError: invalid syntax

    I'm running on latest Django version.

    opened by reeson46 1
  • Django remote forms syntax correction

    Django remote forms syntax correction

    So, my context is the following: I was implementing the django-remote-forms on a Django project and the library ended up crashing several times, until I considered doing some code updates to the own library. This pull request basically contains some simple syntax changes that helped me with the code.

    opened by gabriel-taufer 0
  • FIX-ERROR: ImportError: cannot import name 'force_unicode' from 'djan…

    FIX-ERROR: ImportError: cannot import name 'force_unicode' from 'djan…

    FIX ERROR:

    `ImportError Traceback (most recent call last) in ----> 1 from django_remote_forms.forms import RemoteForm 2 3 from india.forms import FormImporterCPM 4 5 form = FormImporterCPM()

    ~/.virtualenvs/zina-flow/lib/python3.7/site-packages/django_remote_forms/forms.py in 2 3 from django_remote_forms import fields, logger ----> 4 from django_remote_forms.utils import resolve_promise 5 6

    ~/.virtualenvs/zina-flow/lib/python3.7/site-packages/django_remote_forms/utils.py in 1 from django.utils.functional import Promise ----> 2 from django.utils.encoding import force_unicode 3 4 5 def resolve_promise(o):

    ImportError: cannot import name 'force_unicode' from 'django.utils.encoding' (/home/leon/.virtualenvs/zina-flow/lib/python3.7/site-packages/django/utils/encoding.py) `

    opened by loco0321 0
Owner
WiserTogether, Inc.
WiserTogether, Inc.
A Python HTML form library.

Deform Introduction Use cases Installation Example Status Projects using Deform Community and links Introduction Deform is a Python form library for g

Pylons Project 391 Jan 3, 2023
Full control of form rendering in the templates.

django-floppyforms Full control of form rendering in the templates. Authors: Gregor Müllegger and many many contributors Original creator: Bruno Renié

Jazzband 811 Dec 1, 2022
Automate your google form here!

Google Form Filler (GFF) - Automate your google form here! About The idea of this project came from my online lectures as one of my professors takes a

Jay Thorat 13 Jan 5, 2023
Easy and free contact form on your HTML page. No backend or JS required.

Easy and free contact form on your HTML page. No backend or JS required. ?? ??

0xDEADF00D 8 Dec 16, 2022
Bootstrap 3 integration with Django.

django-bootstrap3 Bootstrap 3 integration for Django. Goal The goal of this project is to seamlessly blend Django and Bootstrap 3. Want to use Bootstr

Zostera B.V. 2.3k Dec 24, 2022
Bootstrap 4 integration with Django.

django-bootstrap 4 Bootstrap 4 integration for Django. Goal The goal of this project is to seamlessly blend Django and Bootstrap 4. Requirements Pytho

Zostera B.V. 979 Dec 26, 2022
The best way to have DRY Django forms. The app provides a tag and filter that lets you quickly render forms in a div format while providing an enormous amount of capability to configure and control the rendered HTML.

django-crispy-forms The best way to have Django DRY forms. Build programmatic reusable layouts out of components, having full control of the rendered

null 4.6k Jan 5, 2023
The best way to have DRY Django forms. The app provides a tag and filter that lets you quickly render forms in a div format while providing an enormous amount of capability to configure and control the rendered HTML.

django-crispy-forms The best way to have Django DRY forms. Build programmatic reusable layouts out of components, having full control of the rendered

null 4.6k Dec 31, 2022
A set of high-level abstractions for Django forms

django-formtools Django's "formtools" is a set of high-level abstractions for Django forms. Currently for form previews and multi-step forms. This cod

Jazzband 619 Dec 23, 2022
A fresh approach to autocomplete implementations, specially for Django. Status: v3 stable, 2.x.x stable, 1.x.x deprecated. Please DO regularely ping us with your link at #yourlabs IRC channel

Features Python 2.7, 3.4, Django 2.0+ support (Django 1.11 (LTS), is supported until django-autocomplete-light-3.2.10), Django (multiple) choice suppo

YourLabs 1.7k Jan 1, 2023
MessagePack serializer implementation for Python msgpack.org[Python]

MessagePack for Python What's this MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JS

MessagePack 1.7k Dec 29, 2022
ELF file deserializer and serializer library

elfo ELF file deserializer and serializer library. >>> import elfo >>> elf = elfo.ELF.from_path('main') >>> elf ELF( header=ELFHeader( e_ident=e

Filipe Laíns 3 Aug 23, 2021
An alternative serializer implementation for REST framework written in cython built for speed.

drf-turbo An alternative serializer implementation for REST framework written in cython built for speed. Free software: MIT license Documentation: htt

Mng 74 Dec 30, 2022
A platform independent file lock for Python

py-filelock This package contains a single module, which implements a platform independent file lock in Python, which provides a simple way of inter-p

Benedikt Schmitt 497 Jan 5, 2023
Automatic and platform-independent unpacker for Windows binaries based on emulation

_ _ __ _ __ _ | | | | / / (_) \ \ | | | | | |_ __ | | _ | | _ __ __ _ ___| | _____ _ __

null 514 Dec 21, 2022
Program to send ROM files to Turbo Everdrive; reverse-engineered and designed to be platform-independent

PCE_TurboEverdrive_USB What is this "TurboEverdrive USB" thing ? For those who have a TurboEverdrive v2.x from krikzz.com, there was originally an opt

David Shadoff 10 Sep 18, 2022
Tweak the form field rendering in templates, not in python-level form definitions. CSS classes and HTML attributes can be altered.

django-widget-tweaks Tweak the form field rendering in templates, not in python-level form definitions. Altering CSS classes and HTML attributes is su

Jazzband 1.8k Jan 2, 2023
Tweak the form field rendering in templates, not in python-level form definitions. CSS classes and HTML attributes can be altered.

django-widget-tweaks Tweak the form field rendering in templates, not in python-level form definitions. Altering CSS classes and HTML attributes is su

Jazzband 1.8k Jan 6, 2023
GMailBomber is a form of Internet abuse which is perpetrated through the sending of massive volumes of email to a specific email address with the goal of overflowing the mailbox and overwhelming the mail server hosting the address, making it into some form of denial of service attack.

GMailBomber is a form of Internet abuse which is perpetrated through the sending of massive volumes of email to a specific email address with the goal of overflowing the mailbox and overwhelming the mail server hosting the address, making it into some form of denial of service attack.

Muneeb 5 Nov 13, 2022
Resolve form field arguments dynamically when a form is instantiated

django-forms-dynamic Resolve form field arguments dynamically when a form is instantiated, not when it's declared. Tested against Django 2.2, 3.2 and

DabApps 108 Jan 3, 2023