Passing POST request by AJAX, Django problem - javascript

my view is :
def creating_profile(request):
if request.is_ajax and request.method == "POST":
array = request.POST.get('nums')
print(request.POST.get('nums'))
else:
print('it's not ajax')
my js:
const RegisterForm = document.forms["RegisterForm"];
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
let nums = [1, 2, 3]
RegisterForm.addEventListener('submit', () => {
$.ajax({
headers: { 'X-CSRFToken': csrftoken },
url: '/account/creating-profile/',
type: 'POST',
data: { nums: nums },
success: function (data) {
//
}
});
but it returns None the result of print(request.POST.get('nums')), I would be glad if someone help me about this issue
update :

I'm not extremely familliar with Ajax, but whenever I try to pass data from a form to my view, I use FormData:
form_data = new FormData(document.getElementById("RegisterForm"))
This adds all fields of the form in a dictionnary, where you can access values by the field name. You can add on top of it using .append()
Then in your request you can use
fetch("/account/creating-profile/", {
headers: myHeaders,
body: form_data,
method:"POST"})
And retrieve it in your view using
nums = request.POST["nums"]
Edit :
Your JS would look like this :
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
let nums = [1, 2, 3]
myHeaders = new Headers()
myHeaders.append("X-CSRFToken", csrftoken)
form_data = new FormData(document.forms["RegisterForm"]);
form_data.append("nums", nums) // <-- Here you can add anything to the form data using form_data.append("Key", value)
fetch("/account/creating-profile/", {
headers: myHeaders,
body: form_data,
method:"POST"})
Doing so will POST on your server twice if you don't prevent default POST from happening, you can prevent it doing this :
$(function(){
$("#RegisterForm").submit(function(){
return false
})
})
or by using an event listenner and preventDefault (see docs : https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)

You can use getlist() method to access list object in from POST like this
def creating_profile(request):
if request.is_ajax and request.method == "POST":
array = request.POST.getlist('nums')
print(array)# this will return [1, 2, 3]
else:
print('it's not ajax')
and about MultiValueDictKeyError it occurs if data is not present in your request.POST['key'] than raise MultiValueDictKeyError solution is
use get() method it will return None if given key does not have any value and will not raise any exception.
A data to be sent to the server. It can be JSON object, string or
array.
data: { "nums": nums }
check this doc.

Related

How to pass javascript array of dictionary to flask

I have an array of dictionaries in javascript that I want to send as payload to a POST request to flask.
However, the array always gets sent empty.
Javascript:
{% for department in departments %}
var department_id = "{{ department.id }}"
var cardgroup = $("#cardgroups_{{ department.id }}").val();
var doorgroup = $("#doorgroups_{{ department.id }}").val();
data.push({
department_id: department_id,
cardgroup_id: cardgroup,
doorgroup_id: doorgroup
});
{% endfor %}
$.post("data/save-office/"+office, data={data: data}, function (data) {
if (data['error']) {
alert(data['error']);
}
else
if (data['success']) {
load_table();
}
});
python:
#app.post('/data/save-office/<office>')
def save_office(office):
departments = request.args.getlist('data[]'). # departments = []
I tried to change departments to request.args.getlist('data') but it returned the same thing.
I also tried to use AJAX instead but it was basically the same thing.
Based on only provide an answer to your original question, you can pass an array to flask as the body of a POST request, Flask automatically handles JSON to dict conversion as-is.
Consider this code block as an example of how to send that data:
var my_json_array = [{
"key": "val"
}, {
"key": "val"
}]
async function postData(url = '', data = {}) {
const response = await fetch(url, {
method: 'POST', .
headers: {
'Content-Type': 'application/json'
},
body: data
});
return response.json();
}
postData('http://localhost:5000/test', my_json_array)
.then(data => {
console.log(data);
});
Note: I want to give credit to MDN for the fetch API sample I used on this post, visit https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch to know more about this new JavaScript API feature

How to Parse LocalStorage JSON object in Django View from Ajax?

I am trying to submit localstorage data via a POST request using the below jquery ajax method. How should I write my view so I can Parse my JSON object and get a hold of "product_id" to execute the below command in my Django view. Please see a copy of my view below.
Trying since one week, but I failed to fix the issue
Is there any better way of achieving this ?
My Ajax:
$(document).ready(function() {
var compare = localStorage.getItem("comparisionItems");
var compareObj = JSON.parse(compare);
var data_url = window.location.href;
console.log(compare)
console.log(compareObj)
$.ajax({
url: data_url,
type: "POST",
data: {'compare_id': compareObj },
headers: { "X-CSRFToken": $.cookie("csrftoken") },
success: function (result) {
console.log("Success")
},
});
});
and My Views:
def compare(request):
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax and request.method == "POST":
compare_id= request.POST.getlist('compare_id[itemIds]')
product = get_object_or_404(Products, id=compare_id)
context={ 'product':product}
return render (request, './compare.html', context)
Actually my localStorage is on following format:
("comparisionItems"({ images: products, itemIds: itemIds }));
Can you please help me how can I pass itemIds to views and return item from views for the itemsIds?
Console log for console.log(compareObj)
https://imgur.com/MxdZrgy
since .is_ajax() is deprecated you cant use that, but you can check if the request is an XMLHttpRequest like below.
from django.shortcuts import get_object_or_404
def compare(request):
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax and request.method == "POST":
compare_id = request.POST.get('compare_id')
product = get_object_or_404(Products, product_id=id)
context={ 'product':product,}
return render (request, './ecommerce/compare.html', context)
note; the get_object_or_404 is just a shortcut for:
try:
product = Products.objects.get(product_id=id)
except:
raise Http404

JSON POST request object showing unevaluated keys

I am trying to send an AJAX post request to Django. I have a valid JSON object, which i can print/view/stringify in browser, but when it arrives in Django, the keys are unevaluated (see Django view in 2nd code block).
JS:
/* prettify payload for back */
var makeUpdatePayload = function(fieldType, fieldArray) {
var orderInfo = fieldArray.map(function(field, idx) {
var fieldInfo = field.split('-field-')
return {
'pk': fieldInfo[1],
'order': idx
}
});
return {[fieldType]: orderInfo}
};
/* post payload */
var updateFieldOrder = function( payload ) {
console.log('in ajax')
console.log(JSON.stringify(payload)) // {"search":[{"pk":"9","order":0},{"pk":"7","order":1},{"pk":"6","order":2},{"pk":"8","order":3},{"pk":"5","order":4},{"pk":"4","order":5}]}
$.ajax({
type: "POST",
url: "update_field_order/",
dataType: "json",
data: JSON.parse( JSON.stringify(payload)),
});
};
var payload = makeUpdatePayload('search', ["search-field-9", "search-field-7", "search-field-6", "search-field-8", "search-field-5", "search-field-4"])
updateFieldOrder(payload);
in my django view:
def update_field_order(request, recipe_pk):
print('post')
print(request.POST) # <QueryDict: {'search[0][pk]': ['9'], 'search[0][order]': ['0'], 'search[1][pk]': ['7'], 'search[1][order]': ['1'], 'search[2][pk]': ['6'], 'search[2][order]': ['2'], 'search[3][pk]': ['8'], 'search[3][order]': ['3'], 'search[4][pk]': ['5'], 'search[4][order]': ['4'], 'search[5][pk]': ['4'], 'search[5][order]': ['5']}>
I've tried JSON.stringify then JSON.parse -ing the payload before sending, but this doesn't help, I still see the same formatting. With JSON.stringify(payload), I get the expected output:
`<QueryDict: {'{"search":[{"pk":"9","order":0},{"pk":"7","order":1},{"pk":"6","order":2},{"pk":"8","order":3},{"pk":"5","order":4},{"pk":"4","order":5}]}': ['']}>`
Why is this happening?
I can see that the data is not correctly evaluated on sending:
I'm not entirely sure what you mean by the keys are unevaluated, but to send the object in the POST request, you should stringify it in your ajax call:
data: JSON.stringify(payload),
and then in your view, retrieve the JSON from the request.body and load it using the json module:
import json
...
payload = json.loads(request.body.decode("utf-8"))

django ajax call return 403 bad request

I'm trying to compile project https://github.com/kannan4k/django-carpool
please refer this project repo for this issue.
and end up with following error during ajax call.
Failed to load resource: the server responded with a status of 400 (BAD REQUEST).
I know this is because of ajax post request & CSRF tokens.
following is my setting.
1. disable "django.middleware.csrf.CsrfViewMiddleware"
2. in new_trip page I have a button (Postdata)so this button sends an ajax request.
My View:-
#login_required
def save_journey(request):
if request.is_ajax() and request.method == "POST":
try:
res = json.loads(request.body)
cords = res['cords']
cords = [[x['d'], x['e']] for x in cords]
distance = res['distance']
start_place = res['start']
end_place = res['end']
clusters = clusterize_latlngs(cords, distance)
time = datetime.datetime.strptime(res['time'], "%m/%d/%Y %H:%M")
Trip.objects.create(user=request.user, time=time, cluster=json.dumps(clusters), travel_distance=distance,
start_place=start_place, end_place=end_place)
return HttpResponse()
except:
return HttpResponseBadRequest()
else:
return HttpResponseNotAllowed(['POST'])
Ajax call (home.js)
function postData() {
radius = 0;
var url = "/save_journey/";
var dataType = 'json';
if (type == 'r') {
radius = $('#radius').val();
url = "/get_results/";
dataType = 'html';
}
var data = JSON.stringify({
cords: myroute,
time: document.getElementById('dateStart').value,
start: document.getElementById('startPlace').innerHTML,
end: document.getElementById('endPlace').innerHTML,
radius: radius,
distance: distance
});
$.ajax({
type: "POST",
url: url,
dataType: dataType,
data: data,
success: function (data) {
if (type == 'r') {
window.location.href = "/search_results/";
}
else {
window.location.href = '/trip_success/';
}
},
error: function () {
console.log('Error getting options list...')
}
});
console.log(data);
}
this code is not able to call /save_journey/ URL.
I tried many answers from stack overflow & didn't figure out what is the problem .
You should never disable csrftoken unless you're absolutely sure about what you're doing. It's an important part of the security features implemented in Django.
Here is an example of how you can use Ajax with Django with csrftoken:
You can use Ajax Post to send JSON to Django and then handle the arguments as a dict(). Here is an example:
In browser (JQuery/JavaScript):
function newModule() {
var my_data = $("#my_element").val(); // Whatever value you want to be sent.
$.ajax({
url: "{% url 'modules' %}", // Handler as defined in Django URLs.
type: "POST", // Method.
dataType: "json", // Format as JSON (Default).
data: {
path: my_data, // Dictionary key (JSON).
csrfmiddlewaretoken:
'{{ csrf_token }}' // Unique key.
},
success: function (json) {
// On success do this.
},
error: function (xhr, errmsg, err) {
// On failure do this.
}
});
In server engine (Python):
def handle(request):
# Post request containing the key.
if request.method == 'POST' and 'my_data' in request.POST.keys():
# Retrieving the value.
my_data = request.POST['my_data']
# ...
Hope this helps.

How to post an array of JSON objects to a Struts2 action using jQuery?

Using Struts2.
In my Action I have a List<Person> persons;
In javascript, I have this function:
function mytestfunction() {
var url = "MyAction_mytestfunction.action";
var params = {};
var arr = [];
var p1 = { "firstname" : "John", "lastname" : "Doe"};
var p2 = { "firstname" : "Rob", "lastname" : "Smith"};
arr.push(p1); arr.push(p2);
params["persons"] = arr;
$.post(url, params, function(data) {
console.log("done");
});
}
Problem is, the post() never reaches the action. There are no errors in the logs, nothing.
This all changes if instead of posting objects I post primitives. So when I have a List<Integer> nums in the Action and params["nums"] = [1,2,3]; in javascript, everything is posted fine.
So, is there a way to post JSON objects to a Struts2 action via javascript/jquery?
I should mention that I'm using the struts-jquery plugin, not dojo.
I don't know anything about struts, but this is how I POST objects with json:
$.ajax({
type: "POST",
data: JSON.stringify(SOME_JAVASCRIPT_OBJECT),
contentType: "application/json; charset=utf-8"
// etc: etc
});
you can try as following example:
$.ajax({
type: "Post",
url: "action_name", //you can pass through querystring like actionname?paramname=value
data : {
//here comes your param or array
},
dataType:"json",
contentType: "application/json; charset=utf-8",
});
If you want to pass through querystring type must be GET

Categories