# django-remote-forms **Repository Path**: stoneqp/django-remote-forms ## Basic Information - **Project Name**: django-remote-forms - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-12-26 - **Last Updated**: 2020-12-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 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.