Package: meg-django-remote-forms
# django-remote-formsA package that allows you to serialize django forms, including fields and widgets into Pythondictionary for easy conversion into JSON and expose over APIPlease 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 ImplementationIf you don't mind digging around a little bit to learn about different the components that might benecessary for an implementation of django-remote-forms, check outdjango Remote Admin [django-remote-admin](https://github.com/tarequeh/django-remote-admin)## Usage### Minimal Example```pythonfrom django_remote_forms.forms import RemoteFormform = 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```pythonfrom django.core.serializers.json import simplejson as json, DjangoJSONEncoderfrom django.http import HttpResponsefrom django.middleware.csrf import CsrfViewMiddlewarefrom django.views.decorators.csrf import csrf_exemptfrom django_remote_forms.forms import RemoteFormfrom my_awesome_project.forms import MyAwesomeForm@csrf_exemptdef my_ajax_view(request):csrf_middleware = CsrfViewMiddleware()response_data = {}if request.method == 'GET':# Get form definitionform = MyAwesomeForm()elif request.raw_post_data:request.POST = json.loads(request.raw_post_data)# Process request for CSRFcsrf_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 CSRFcsrf_middleware.process_response(request, response)return response```## djangocon ProposalThis is a bit lengthy. But if you want to know more about my motivations behind developing django-remote-formsthen 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.