Pass json and deserialize form in django

The problem is as follows: I am sending some data with ajax to the server. This data looks like this:

data = {
  form : $(this).serialize(),
  some_array: [2,3,4,1]
}

      

How do I get a form object in django? request.POST['form']

returns a string with a form. I am trying to use a library import json

.

But when I run value = json.load(request.POST['some_array'])

or form = json.load(request.POST['form'])

it doesn't work.

Printing request.POST['form']

returns the following:

u'csrfmiddlewaretoken=I3LWAjfhZRGyd5NS3m9XcJkfklxNhxOR& address_city=%D0%9A%D0%B8%D1%97%D0%B2& address_street=2& address_building=3& delivery_time=2015-05-15'

+3


source to share


2 answers


The form data is not JSON encoded, but as a query string. You can use urlparse.parse_qs

from the standard library to parse this query string.

Example:



from urlparse import parse_qs


form_data = parse_qs(request.POST['form'].encode('ASCII'))  # Query strings use only ASCII code points so it is safe.

# To access address_city:
address_city = form_data['address_city'][0].decode('utf-8')

# If you plan to pass form_data to a Django Form,
# use QueryDict instead of parse_qs:
from django.http import QueryDict


form_data = QueryDict(request.POST['form'].encode('ASCII'))

      

+2


source


Solution 1

Alternatively for aumo's response and assuming you are using jQuery, you can actually use .serializeArray()

instead .serialize()

to create a JSON object, which you can then JSON.stringify and POST.

data = {
  form : $(this).serializeArray(),
  some_array: [2,3,4,1]
};

$.ajax(url, {
  data: JSON.stringify(data),
  contentType: 'application/json',
  type: 'POST',
});

      

As you noted in the comments, the serializeArray

JSON output format is not easy to use in Django form and requires further processing after the content is deserialized via json.load

.

data = json.load(request)
value = data['some_array']

form_data = {}
for f in data['form']:
    if f not in form_data:
        form_data[f['name']] = f['value']
    elif not isinstance(form_data[f['name']], list):
        form_data[f['name']] = [form_data[f['name']], f['value']]
    else:
        form_data[f['name']].append(f['value'])

form = MyForm(data=form_data)

      

Solution 2



After a different look at the code, it might be better (and more general for future security) to serialize the form data to the proper json format in the frontend.

There are many solutions for this though; your best bet would be to go with a tested / popular library like jquery-serialize-object , the code change would be small:

<script src="jquery.serialize-object.min.js"></script>
<script>
    data = {
      form : $(this).serializeObject(),
      some_array: [2,3,4,1]
    };

    $.ajax(url, {
      data : JSON.stringify(data),
      contentType : 'application/json',
      type : 'POST',
    });
</script>

      

And then the server code will be much simpler

data = json.load(request)
value = data['some_array']
form = MyForm(data=data['form'])

      

0


source







All Articles