Django get wrong value from json.loads in POST request - django

I need to pass a user-input geojson with request to further process the information. The data comes from a textfile and then passed to the views.py in django with a POST request. Before passing to the view I checked the value of the string and that appears to be correct. After passing that to the view, I made a print check and some values inside the JSON are changed in string like:
"{"id": "13871", "type":SOH# "Feature", "properties": {"lanes": 0, "highway": "pedestrian" etc....."
or
"{"id":"86","type":"FeatureSOHVT","properties":etc......."
The bold strings sometimes appear even inside the values of the dictionary.
The js file:
$.ajax({
type: 'POST',
url: $('#confImp').data('url'),
dataType: 'json',
data: {'streetWeb': JSON.stringify(street_web), 'int_points': JSON.stringify(int_points_loaded), 'csrfmiddlewaretoken': csrftoken,},
success: function(res){blablabla}
The django views.py:
elif 'streetWeb' in request.POST:
print(json.loads(request.POST.get('streetWeb')))
request.session['Working_area_final'] = json.loads(request.POST.get('streetWeb'))
print(json.loads(request.POST.get('int_points')))
request.session['int_points'] = json.loads(request.POST.get('int_points'))
return JsonResponse({'Risposta': 'Done'})

Related

copyleaks sent pdfReport to endpoint as binary on request.body, not as file

I have django view that gets request and I try to send pdf result of copyleak scan.
I get file as request.body and request.FILES is empty.
I have checked copyleaks docs to see if I could pass extra argument as we should pass
enctype="multipart/form-data" in django form to get files in request.FILES, but I did not see anything related.
I can read request body and write it to file, no problem here, but would be great if I directly get pdf file in request FILES.
myobj = json.dumps(
{
"pdfReport": {
"verb": "POST",
"endpoint": "https://aa67-212-47-137-71.in.ngrok.io/en/tool/copyleaks/download/",
},
"completionWebhook": "https://aa67-212-47-137-71.in.ngrok.io/en/tool/copyleaks/complete/",
"maxRetries": 3,
}
)
response = requests.post(
"https://api.copyleaks.com/v3/downloads/file4/export/export16",
headers=headers,
data=myobj,
)
I tried to change Content-Type manually and got error
django.http.multipartparser.MultiPartParserError: Invalid boundary in multipart: None
Bad request (Unable to parse request body): /en/tool/copyleaks/download/

Get query list parameter from Datatable in Django

I'm using DataTable with django and I'm trying to set up the serverSide option. Everything is working fine except the order parameter. Datatable is sending all the parameters to the backend in which the order comes like this:
order[0][column]: 0
order[0][dir]: asc
order[1][column]: 2
order[1][dir]: desc
I'm trying to get all the order parameters in a list with the getlist() function but I'm getting everytime an empty list
orders = request.GET.getlist('order[]')
What am I missing?
Ok, I found the solution. I was sending the ajax as a form-encoded and it was getting the keys for order as a literal string order[0][column] order[0][dir]. What I had to do is send the ajax in datatable as a JSON and get the parameters with json.loads() in the view:
DataTable
"ajax": {
"url": url,
"contentType": "application/json",
"type": "POST",
"data": function (d) {
return JSON.stringify(d);
}
},
View
request_data = json.loads(request.body)
dt_draw = request_data.get('draw')
dt_start = request_data.get('start')
dt_length = request_data.get('length')
dt_search = request_data.get('search').get('value')
dt_order = request_data.get('order')
Typicall you get an empty list for getlist if the keyword you are looking for does not exist. Try request.GET.getlist('order') instead.

Getting an array from POST in django issue

Client side:
$fk_fields=[];
$fk_fields.push({'a':1,'b':2});
$fk_fields.push({'a':3,'b':4});
$data = {'fk_fieldss': $fk_fields};
$.ajax({
type: "POST",
url: "../getFormMetaData/",
cache:false,
data: $data,
success: createZoomDialog,
error: displayAjaxError
});
Server side:
fk_fields=request.POST.getlist('fk_fieldss')
print fk_fields
What ever i try no success. Always i get an empty string while other non aray values are ok. if i do print request.POST i see values in post but i cannot get array from that. Why?
UPDATE
Here is how look's like print request.POST:
<QueryDict: {u'fk_fieldss[0][b]': [u'2'], u'fk_fieldss[1][b]': [u'4'], u'fk_fieldss[0][a]': [u'1'], u'fk_fieldss[1][a]': [u'3']}>
SOLUTION
client side:
$data = {'fk_fieldss': JSON.stringify($fk_fields)};
server side:
fk_fields = json.loads(request.POST['fk_fieldss'])
You need to encode your array into json string on js side and then decode it in django:
in js
data: JSON.stringify($data),
then in django:
fk_fields = json.loads(request.POST)['fk_fieldss']

Ajax, CSRF and DELETE

I use the getCookie function from the django documentation to get the csrfmiddlewaretoken value.
I have the following ajax call:
var url = reverse_removeprofile.replace(/deadbeef/, key);
$.ajax({
type: "DELETE",
url: url,
data: "csrfmiddlewaretoken=" + getCookie("csrftoken"),
success: function() { ... },
});
When this code gets executed then django raises a 403 exception telling me that the CSRF verification failed. However, if I change the type from DELETE to POST then django is happy about it and doesn't complain at all.
I was not really able to find something useful in Google about this, but I've found this (now closed and fixed) ticket: https://code.djangoproject.com/ticket/15258
If I understand it correctly then this issue has been fixed in the 1.4 milestone. I use django 1.4 but still I cannot verify the CSRF token with a DELETE request.
Am I missing something here?
This appears to be a jQuery bug, caused by some confusion as to whether DELETE data should be attached to the URL (like a GET request) or the request body (like a POST)
See this bug report.
You can probably get around this by using the alternative CSRF method for AJAX calls, setting an X-CSRFToken header on the request. Try changing your AJAX call to look like this:
$.ajax({
type: "DELETE",
url: url,
beforeSend: function(xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie("csrftoken"));
},
success: function() { ... },
});
Please note, when it comes to DELETE requests DJango does not check for csrfmiddlewaretoken in the request body. Rather it looks for X-CSRFToken header
Coming to working of DJango CSRFMiddleware you can see the source code of django > middleware > csrf.py > CsrfViewMiddleware in which it is very clear that DJango does not scan for csrfmiddlewaretoken in request body if the request is of DELETE type:
# Check non-cookie token for match.
request_csrf_token = ""
if request.method == "POST":
try:
request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
except OSError:
# Handle a broken connection before we've completed reading
# the POST data. process_view shouldn't raise any
# exceptions, so we'll ignore and serve the user a 403
# (assuming they're still listening, which they probably
# aren't because of the error).
pass
if request_csrf_token == "":
# Fall back to X-CSRFToken, to make things easier for AJAX,
# and possible for PUT/DELETE.
request_csrf_token = request.META.get(settings.CSRF_HEADER_NAME, '')

Send Json via $.load() of jQuery in a GET request to Django

Happy coding weekend to everyone!!!.
I'm stuck trying to send a JSON object via $.load() of jQuery, i want to send it with the GET method, this is the code that i have in my javascript code, I attached the Ajax request that receives the JSON Object for clarity:
function ajaxLoadClasses() {
$.ajax({
url: 'load_classes/',
type: 'GET',
dataType: 'json',
success: function(json) {
$.each(json, function(iterator,item) {
loadViaGet(item);
});
},
error: function(xhr, status) {
alert('Sorry, there was a problem!');
},
complete: function(xhr, status) {},
});
}
function loadViaGet(item) {
$div = $('div.myClass');
//Here is where I'm stuck, I'm not sure if this is the way to send the JSON obj
$div.load('thisAppURL/?json=' + encodeURIComponent(item), function() {
alert('Load was performed');
});
}
The "item" json obj received was made out of a Model of Django using
jsonToSendToAjax = serializers.serialize('json', obj)
And I don't think that I'm using the correct methods in my Django to deserialize the JSON object or to convert the JSON object into a Python object so I can handle it in my view and send it to a template:
def popUpForm(request):
jsonData = request.GET['json']
deser = serializers.deserialize('json', jsonData)
#This could be another way to convert the JSON object to a Python Object
#pythonObj = simplejson.loads(jsonData)
return render_to_response('class_pop_up_form.html', deser)
It will be very helpful if someone can help me with this!! I'm really struggling with it but I don't find the right way to do it.
EDIT 1 :
I want to send the JSON object via the GET with the $.load() function, not with the POST method,as I read in the jQuery api: http://api.jquery.com/load/ the $.load() method works as follow: .load( url, [data], [complete(responseText, textStatus, XMLHttpRequest)] )
The POST method is used if data is provided as an object; otherwise, GET is assumed.
EDIT 2:
Forget about sending the json object via the GET method, now I'm using the POST method, but now I don't figure out how to use that json object in my Django View.py, don't know if i need to deserialize it or not, the format of the json object that I'm using is the following:
{"pk": 1,
"model": "skedified.class",
"fields": {
"hr_three": null,
"group": 1,
"name": "Abastecimiento de agua",
"day_three": null,
"day_one": "1 , 3",
"hr_one": "10+/3",
"online_class": null,
"teacher_name": "Enrique C\\u00e1zares Rivera / ",
"day_two": null,
"class_key": "CV3009",
"hr_two": null }
}
This isn't how jQuery suggests you should send the data and it's probably not a good idea to do it this way either. Your url gets very ugly and long very quick if you add the json string to it like that.
Use the second argument for $.load; "data" (see http://api.jquery.com/load/) instead. So something like
$div.load('thisAppURL', {"json": encodeURIComponent(item)});
Also, if you want to trace the output, I'd sugest using the third argument, the callback function, and use console instead of alert. You can get the actual return from the server that way too. So you'd get something like:
$div.load(
'thisAppURL',
{"json": encodeURIComponent(item)},
function(response, status, xhr){
console.log(response);
}
);
the question was not clear to me but you can send json via load as the second argument
$div = $('div.myClass');
//Here is where I'm stuck, I'm not sure if this is the way to send the JSON obj
$div.load('thisAppURL/?json=' + encodeURIComponent(item),{"name":"john","age":"20"}, function() {
alert('Load was performed');
});
for converting javascript array to json see this answer Convert array to JSON
and for deserializing json in django Django Deserialization