AJAX/PYTHON : how to send json value to server - python

I am a new to Ajax/Python, I don't know how to POST a json value to my python server.
Python code:
#app.route('/ajouterContact', methods = ['POST'])
def ajouterContact():
data = json.loads(request.data)
#nom = request.form['nomContact'];
contact.append(data)
ajouter.make_response(json.dumps(contact), 201)
ajouter.headers['Content-Type'] = 'application/json'
JS code
$('#buttonAjouter').click(function() {
var nom = 'Tom';
var myObj = new Object();
myObj.nom = nom;
var jsonText = JSON.stringify(myObj);
var i = 0;
$.ajax({
url: '/ajouterContact',
data: jsonText,
type: 'POST',
dataType: "json",
success: function(response) {
console.log(response);
},
error: function(error) {
console.log(error);
}
});
});
I am getting this error on server side :
ValueError: No JSON object could be decoded
If anyone can help me on this..
Thank you!

You need to provide the contentType in your ajax request:
contentType: 'application/json;charset=UTF-8',
Then in your server try to debug something like this:
request.json

Related

Updating database after reordering Datatable

I'm struggling with the datatables reordering. I want when user reorder to update table in the database. For this to happen i need:
to configure the datatable to send request to the server.
send the information about reordered datatable to flask endpoint.
Process data on the backend and update database table.
I have read the documentation but it is not clear to me.
My code:
$(document).ready(function () {
var dt = $('#data').DataTable({
rowReorder: true,
dom: 'Bfrtip'
});
});
My own solution:
JavaScript code:
dt.on('row-reorder.dt', function (e, details, edit) {
var slownik = {};
for (var i = 0, ien = details.length; i < ien; i++) {
let id_asortymentu = details[i].node.id;
let nowa_pozycja = details[i].newPosition+1;
console.log(id_asortymentu);
console.log(nowa_pozycja);
slownik[id_asortymentu] = nowa_pozycja;
}
req = $.ajax({
url: 'asortymenty/tabela_reorder',
dataType: "json",
type: 'POST',
data : JSON.stringify(slownik)
});
req.done(function(data){
if (data.result == 1){
console.log('Table reordered.');
}
});
});
Flask backend code:
#admin.route('asortymenty/tabela_reorder', methods = ['GET','POST'])
def table_reorder():
slownik=request.get_json('data')
for key, value in slownik.items():
asort = Asortyment.query.get(key)
print(asort.pozycja)
asort.pozycja = value
db.session.add(asort)
db.session.commit()
return jsonify({'result' : '1'})

Error trying to save data in django via ajax(fetch)

I have a model that references other models, I am trying to save data using ajax
Example:
class Friend(models.Model):
name = ...
class Main(models.Model):
name = ....
friend = models.ForeignKey(Friend, on_delete=models.CASCADE)
All body comes from ajax(fetch) request
I have a table (html), and add data to cells, then with the
enter event, send data.
Like this:
input.addEventListener("keyup", function (e) {
//in this scenario I already have the whole row
// get full_row `row_data`
post_ajax = {
method: "POST",
headers: {
"X-CSRFToken": crf_token, // I get it with a regular expression
"Content-Type": "application/json",
"X-Requested-With": "XMLHttpRequest",
Accept: "application/json",
},
body: JSON.stringify(row_data),
};
fetch("my_url", post_ajax)
.then((res) => res.json())
.catch((error) => console.error("Error:", error))
.then((response) => console.log("Success:", response));
});
My view function
def save_post(request):
if request.is_ajax and request.method == "POST":
body_unicode = request.body.decode('utf-8')
data = json.loads(body_unicode)
print('here the data arrives',data)
# here the data arrives {'name': 'Ale', 'friend_id': 22}
Main.objects.create(name=data['name'], friends=data['friend_id'])
return JsonResponse({"instance": data}, status=200)
return JsonResponse({"error": ""}, status=400)
This is the error
raise TypeError("%s() got an unexpected keyword argument '%s'" %
(cls.__name__, kwarg))
TypeError: Main() got an unexpected keyword argument 'Friends'
Any idea or suggestion?
EDIT:
When you are creating the Main object, try making the "friend" attribute an object, like this:
friend = Friend.objects.get(id=data['friend_id'])
Main.objects.create(name=data['name'], friend=friend)
Also, the main issue appears to be you are calling the column "friends" but it should be "friend" when you are creating the Main object.
This:
Main.objects.create(name=data['name'], friends=data['friend_id'])
Should be:
Main.objects.create(name=data['name'], friend=data['friend_id'])
PREVIOUS ANSWER:
Assuming you are using JQuery in the template to send an AJAX request, since you did not specify.
In your urls.py:
...
path('/api/post_friend/', post_friend_api, name="post_friend_api"),
...
In your template :
<script type="text/javascript">
$("#myBurron").click(function(){
var csrfToken = $( "input[name='csrfmiddlewaretoken']"); // assuming this is a form
var friend_name = $("#friend_name").val();
$.ajax({ url: '{% url 'post_friend_api' %}',
type: "POST",
dataType: "json",
data: {'friend':friend_name, 'csrfmiddlewaretoken':csrfToken.val()},
cache: false
}).done(function(data) {
if (data.result === true){
alert(data.message);
}
});
});
});
</script>
In your views.py:
from django.http import JsonResponse
def post_friend_api(request):
data = {}
if request.POST.get('friend', None) is not None:
friend_name = request.POST.get('post_note')
# save the object and indicate success
data['result'] = True
data['message'] = "Friend saved successfully"
...
if request.is_ajax():
return JsonResponse(data)
else:
return HttpResponseBadRequest()
When you are sending data via POST don't forget to pass along your CSRF token as in the example above. This assumes you have a form on the page you can get it from, otherwise you can use something like this to get it:
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
If you don't want to deal with the CSRF token, you can mark the view with the #csrf_exempt decorator and remove the 'csrfmiddlewaretoken' data element from the Ajax call in the template, but it may not be ideal or the most secure. An example of that:
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse
#csrf_exempt()
def post_note_api(request):
...
If you post more details I can update my answer.

Python string is null but also isn't None nor empty string

class StartAnalysis(BaseHandler):
def post(self):
playlist = self.request.get('playlist')
language = self.request.get('language')
If I make a POST request without this playlist field, then this happens:
>>> playlist
null
>>> type(playlist)
<type 'unicode'>
>>> playlist is None
False
>>> not playlist
False
>>> playlist == ''
False
>>> playlist == u''
False
How am I supposed to check that it's None? And why is it saying that it's null and not None?
I'm using AppEngine.
My javascript code making the POST request:
let params = new URLSearchParams(location.search);
let url_id = params.get('id');
let url_language = params.get('language');
const url = 'http://localhost:8080/start-analysis?playlist=' + url_id + '&language=' + url_language;
$.ajax({
url: url,
type: 'POST',
success: function(results) {
...
},
error: function(error) {
...
}
});
I changed to using application/json for the POST requests instead of the default application/x-www-form-urlencoded and that seemed to fix the problem of the request sending the string "null" instead of just an empty string when one of the parameters was empty or missing.
let params = new URLSearchParams(location.search);
let url_id = params.get('id');
let url_language = params.get('language');
const url = 'http://localhost:8080/start-analysis';
$.ajax({
url: url,
type: 'POST',
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify({'playlist': url_id,'language': url_language}),
success: function(results) {
...
},
error: function(response, status, error) {
...
}
});
And the backend receives it like:
class StartAnalysis(BaseHandler):
def post(self):
data = json.loads(self.request.body)
playlist = data['playlist']
language = data['language']

Download CSV file to the client

I have the following route:
#app.route('/download/', methods=['GET'])
def download():
output_filename = request.args.get('output_filename')
data = dict(foos=[1,2,3,3,2,1], bars=[7,7,7,7,7,7])
df = pd.DataFrame(data)
result = df.to_csv(index=False)
response = make_response(result)
response.headers['Content-Disposition'] = f'attachment; filename={output_filename}'
response.headers['Cache-Control'] = 'must-revalidate'
response.headers['Pragma'] = 'must-revalidate'
response.headers['Content-type'] = 'application/csv'
return response
which I'm calling with AJAX as follows:
function download(data, handler = null) {
let data = {output_filename: "foo.csv"};
let url = "/download/";
$.ajax({
type: "GET",
url: url,
data: data,
success: function(data) {
console.log('success');
},
});
}
However, nothing's appearing on the client side. Am I missing something here?
Im more familiar with node than ajax ( i had the same issue in nodejs which i fixed here on stackoverflow), but maybe this will help:
$.ajax({
async: false,
from How do I make jQuery wait for an Ajax call to finish before it returns?

can't access json object from python method

I've looked at many answers showing how to access a json in a python method however I can't seem to get mine to work.
Here is my ajax call
var data = {
'customer': customer,
'custID': custID,
'date': date,
'jobNum': jobNum,
'deviceID': deviceID
}
//create customer
if (custID === undefined) {
$.ajax({
url: "http://127.0.0.1:6543/test",
type: "POST",
data: JSON.stringify(data),
dataType: 'json',
success: function(response, textStatus, jqXHR) {
alert(response);
},
error: function(jqXHR, textStatus, errorThrown){
alert(textStatus, errorThrown);
}
});
}
else {
//empty
}
and here is my python method:
#view_config(route_name="test", renderer='templates/main.html')
def new_sheet(request):
response = request.POST
myObject = json.loads(response)
#print myObject["customer"]
test = "hello"
return dict(test=test)
somewhat new to python so pardon my limited understanding. How can I get my json and access the object properties? all i get in my cmd when i tried print was ValueError: No JSON object could be decoded
pyramid has native JSON request support. Set the contentType parameter to application/json to tell the server that you are sending JSON, preferably with a character set (UTF8):
$.ajax({
url: "http://127.0.0.1:6543/test",
type: "POST",
data: JSON.stringify(data),
contentType: 'application/json; charset=utf-8'
dataType: 'json',
success: function(response, textStatus, jqXHR) {
alert(response);
},
error: function(jqXHR, textStatus, errorThrown){
alert(textStatus, errorThrown);
}
});
and on the server side use request.json_body:
#view_config(route_name="test", renderer='templates/main.html')
def new_sheet(request):
myObject = request.json_body
print myObject["customer"]
test = "hello"
return dict(test=test)

Categories