Getting an array from POST in django issue - django

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']

Related

Django get wrong value from json.loads in POST request

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'})

Django Json post request Payload error

Hi I am accessing an url with payload.
I tried this code for payload:
app_id = "Dert/dedff/12i="
payload = "{\n \"app_id\": \"{}\"\n}".format(app_id)
When do request, Django give following error.
Request Method: GET
Request URL: http://127.0.0.1:8000/
Django Version: 1.10.4
Exception Type: KeyError
Exception Value:
"\n 'app_id'"
I tried below code
app_id = "Dert/dedff/12i="
payload = "{{\n \"app_id\": \"{}\"\n}}".format(app_id)
It worked.
Instead of single braces, double braces are required.

Return data as json from odoo 9

I want get data in JSON format from odoo controllery.py
Example:
import openerp.http as http
from openerp.http import request
class MyController(http.Controller):
#http.route('/test_html', type="http", auth="public")
def some_html(self):
return "<h1>Test</h1>"
#Work fine when open http://localhost:8069/test.html
#http.route('/test_json', type="json", website=True, auth="public")
def some_json(self):
return [{"name": "Odoo", 'website': 'www.123.com'}]
How get data in json format, I want data from json read in other app with ajax.
Is it possible view json after open url http://localhost:8069/test_json ???
The important part is to define the contentType of your request properly.
import json
#http.route('/test_json', type="json", auth="public")
def some_json(self):
return json.dumps({"name": "Odoo", 'website': 'www.123.com'})
In your client using javascript you can request the json like this.
$.ajax({
type: "POST",
url: "/test_json",
async: false,
data: JSON.stringify({}),
contentType: "application/json",
complete: function (data) {
console.log(data);
}
});
Or using requests in python
import requests,json
res = requests.post("http://localhost:8069/test_json",data=json.dumps({}),headers={"Content-Type":"application/json"})
To access the response body
body = res.text
As to whether you can simply open a browser and view the json. No, not by default.
Here is what I get
Bad Request
<function some_json at 0x7f48386ceb90>, /test_json: Function declared as capable of handling request of type 'json' but called with a request of type 'http'
You could probably do something pretty fancy with a controller if you really wanted to be able to view it in a browser as well as make json requests. I would post a second question though.
Your controller endpoint looks ok and should function correctly, so I guess your main question is how to test it.
Once you declare that the endpoint type is json, Odoo will check that the request content type header is in fact JSON, so in order to test it your requests will need to have Content-Type: application/json header set. This is a bit difficult using a regular browser, unless you edit the request headers before seinding or call your JSON endpoint from JavaScript via Ajax.
Alternatively, you can test your API from command line using a tool like curl:
curl 'http://localhost:8069/test_json' -H 'Content-Type: application/json' --data "{}"
--data "{}" here indicates an empty JSON structure which will be passed to your endpoint as request parameters.
Please note that you might also have to pass an additional header containing your session_id cookie if you are using more than one Odoo database.

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