Skip to main content

A platform independent form serializer for Django.

Project description

# 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](http://www.slideshare.net/tarequeh/django-forms-in-a-web-api-world)
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](https://github.com/tarequeh/django-remote-admin)

## Usage

### Minimal Example

```python
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:

```json
{
"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

```python
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.

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

meg_django_remote_forms-1.2.1-py2-none-any.whl (13.4 kB view hashes)

Uploaded Python 2

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page