Install

Install the app

From PyPI

$ pip install django-formidable

From Github

You can also install django-formidable via GitHub:

pip install git+https://github.com/peopledoc/django-formidable.git

Configure the app

Before you can use the app, some things need to be configured in order to get it fully operational. django-formidable has the ability to handle different roles and accesses on a per form basis. This is useful when you have multiple types of user accessing the same form. If you don’t need multiple roles, just create a single unique role, this will be enough.

Configure access-rights

First of all, you need to declare all available roles inside your application. To do this, create an formidable.accesses.AccessObject per role needed.

from formidable.accesses import AccessObject

jedi = AccessObject(id='jedi', label='Jedi')
padawan = AccessObject(id='padawan', label='Padawan')

Once your roles are defined, you will need to create a function to return them, in your projects (for the purposes of this example, we’re assuming the function will be created in the module yourproject.access_rights):

def get_access_rights():
    return [jedi, padawan]

The main idea is to create a function which can be called by django-formidable to get the declared roles you defined previously. To tell django-formidable where the function is located, you need to add FORMIDABLE_ACCESS_RIGHTS_LOADER to your settings:

FORMIDABLE_ACCESS_RIGHTS_LOADER = 'yourproject.access_rights.get_access_rights'

Fetch the context

When the content of a contextualised form are required, e.g. to render it in a JavaScript front-end, django-formidable needs to know which context to fetch in order to render the correct fields with the right permissions.

To do this, we’ll need to write some code which will be called by django-formidable.

Let’s assume your user model has a user_type attribute on it. In this case, you could write the following function:

def get_context(request, kwargs):
    return request.user.user_type

The request is a standard Django request, as found in any view. Likewise, kwargs is a standard dictionary of keyword arguments. Of course, the user type should correspond to the id of the AccessObject

Next fill the setting key FORMIDABLE_CONTEXT_LOADER:

FORMIDABLE_CONTEXT_LOADER = 'yourproject.access_rights.get_context'

Formidable’s URLs

URLs are defined in formidable.urls. You can load them with the following line:

url(r'^api/', include('formidable.urls', namespace='formidable'))

URLs accesses

The Formidable views are built with djangorestframework and use the related permissions in order to handle accesses. So, you can write your own permissions with djangorestframework and use it in django-formidable views.

By default, a restrictive permission is applied on all API views if nothing is specified in django settings.

You can specified a list of permissions classes to all the API views by providing the configuration key FORMIDABLE_DEFAULT_PERMISSION:

FORMIDABLE_DEFAULT_PERMISSION = ['rest_framework.permissions.AllowAll']

There are two kinds of views,

1. views which allow to create or edit forms (handled by FORMIDABLE_PERMISSION_BUILDER) 2. views to use the form previously defined (handled by. FORMIDABLE_PERMISSION_USING).

You can provide any permissions you want.

CSRF

If you’re dealing with logged-in users (you surely do), you’re going to need to provide a CSRF Token when validating a creation or an edit form. If you don’t provide it or if your CSRF is misconfigured, you’ll receive a 403 error when trying to save your forms.

In order to do so, you’ll have to use a code similar to this:

function setupCRSFToken(csrftoken) {
  $.ajaxSetup({
    beforeSend: function(xhr, settings) {
      if (!/^(GET|HEAD|OPTIONS|TRACE)$/.test(settings.type) && !this.crossDomain) {
        xhr.setRequestHeader("X-CSRFToken", csrftoken);
      }
    }
  });
}

Warning

you’ll have to make sure that your CSRF configuration is properly set (middlewares, context managers, etc).

Then in your templates, those that’ll have to display and handle the form editor, you’ll have to call this function like this:

<script src="{% static "assets/csrftoken.js" %}"></script>
<script type="text/javascript">
    $(document).ready(function() {
        setupCRSFToken('{{ csrf_token }}');
    });
</script>

This way, every AJAX call coming from this template will provide a token that’ll fit Django’s (and Django REST Framework) requirements.