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'
source to share
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'))
source to share
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'])
source to share