Decode JSON in flask - python

i want to send JSON format data in my flask app using AJAX call,
when i send it i got "None" in flask.
here is jquery,
$('#form').on('click',function(){
var text = $('#textField').val();
var obj = {name:text};
var myJSON = JSON.stringify(obj);
$.ajax({
data : myJSON,
url: '/process',
type : 'post',
contentType: 'application/json',
dataType : 'json'
})
})
here is my Flask route,
#app.route('/process',methods=["POST"])
def process():
data = request.json
return render_template("form.html",data = data)
in data i got "None".

return render_template is not fruitful as data is being sent via Ajax. It will return the template contents.
You can receive the data returned from Flask via done method in Ajax.
I am adding an example code to demonstrate how to handle Ajax submission with JSON data.
app.py:
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
#app.route('/process',methods=["GET", "POST"])
def process():
if request.method == 'POST':
data = request.json
return jsonify(data)
return render_template("form.html")
app.run(debug=True)
form.html:
<html>
<head>
<title>Form</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div id="data"></div>
<input type="text" id="textField" />
<button id="demo_btn">Dummy button</button>
<script>
$(document).ready(function () {
$("#demo_btn").on("click", function() {
var text = $('#textField').val();
var obj = {name:text};
var myJSON = JSON.stringify(obj);
$.ajax({
url: '/process',
type : 'post',
contentType: 'application/json',
dataType : 'json',
data : myJSON
}).done(function(result) {
$("#data").html(result["name"]);
}).fail(function(jqXHR, textStatus, errorThrown) {
console.log("fail: ",textStatus, errorThrown);
});
});
});
</script>
</body>
</html>
Output:
Reference:
http://api.jquery.com/jquery.ajax/

It looks like JQuery isn't setting the correct header.
If you use the request.get_json() method instead of the request.json property it will get json irrespective of the header.

Related

Getting information from Jquery in Django views

in the jquery script, I get the information from the table into the data variable in json format:
<script>
var $table = $('#table')
var $button = $('#button')
$(function() {
$button.click(function () {
data = JSON.stringify($table.bootstrapTable('getData'))
$.ajax({
url: "{%url 'addCampaign'%}",
type: "POST",
data: {
'mails_inf': data,
'csrfmiddlewaretoken': '{{ csrf_token }}',
}
})
})
})
</script>
And in the function with views, I try to get this list for further processing as follows:
def add_campaign(request):
error = ''
if request.method == 'POST':
data = request.POST.get('mails_inf')
print(data)
But the data variable turns out to be None, when alerting this variable in the script itself, all the information is there.
My tab where it all happens handles this url:
path('addCampaign', views.add_campaign, name='addCampaign')
I would be grateful if you could tell me where I am wrong, or offer another solution to the problem

Django view not getting ajax request

I have a script in my template that tries to send data to a django view during onbuttonclick event. My problem is that the request doesn't seem to make it to the view. The browser console sees the request properly and all, but the django view does't even return true when i call request.is_ajax().
request.method returns GET instead of POST, and the data is empty. This behavior is persistent regardless of the request type.
html
<a onclick="setGetParameter(this)" pid="some_id">Some Text</a>
.js
<script>
var csrftoken = Cookies.get('csrftoken');
function setGetParameter(el){
var stuff = $(el).attr('pid');
$.ajax({
type: 'POST',
headers: { "X-CSRFToken": csrftoken },
url: '/view_url/',
data: {'datatopass': stuff},
success: function(response){
alert(response);
}
});
}
</script>
urls.py
path('view_url/', views.test),
path('', views.home),
views.py
def test(request):
output = request.is_ajax()
return HttpResponse(output)
In Django 3.1 is_ajax() method is deprecated. See Miscellaneous Django 3.1
So for Django >= 3.1 you can do it like that:
if request.headers.get('x-requested-with') == 'XMLHttpRequest':
is_ajax = True
else:
is_ajax = False
And make sure that the following line added in AJAX request headers:
"X-Requested-With": "XMLHttpRequest"
I would be use jQuery click method:
<a pid="some_id">Some Text</a>
<script>
var csrftoken = Cookies.get('csrftoken');
function setGetParameter(el){
var stuff = $(el).attr('pid');
$.ajax({
type: 'POST',
headers: { "X-CSRFToken": csrftoken },
url: '/view_url/',
data: {'datatopass': stuff},
success: function(response){
alert(response);
}
});
}
$(document).ready(function(){
$('a[pid]').click(function(){
setGetParameter(this);
});
});
</script>
Also I would be use JsonResponse objects:
from django.http import JsonResponse
def test(request):
output = request.is_ajax()
return JsonResponse({'is_ajax': output})
In order to serialize objects other than dict you must set the safe parameter to False:
response = JsonResponse([1, 2, 3], safe=False)
After days of beating my head against a wall, I chose to go with a different implementation. It appears I can only render the data on the page that initially sent the request.

How to send out an AJAX request to Flask

I'm trying to send an AJAX request to my server to obtain a string and save it.
This is my relevant JS:
var token = "";
$.ajax({
type: 'GET',
url: 'payment_demo.py',
success: function(data) {
token = data;
},
});
This is my relevant Python (Flask):
#app.route('/')
def home():
return render_template('official_checkout_page.html')
#app.route("/", methods=["GET"])
def client_token():
return gateway.client_token.generate()
The HTML and JS both are loaded, but I get a 404 not found on the ajax URL (payment_demo.py).
Right now the locations are /payment_demo.py, /static/official_checkout_page.js (the JS file), /templates/official_checkout_page.html (the HTML file, if necessary). What am I doing wrong?
the ajax request just get data from the spesifik url from server/api resource, please try this code
$.ajax({
type: 'GET',
url: '/api/token',
success: function(data) {
token = data;
},
});
the example Flask code from backend server
from flask import jsonify, render_template
#app.route('/')
def home():
return render_template('official_checkout_page.html')
#app.route("/api/token", methods=["GET"])
def client_token():
return jsonify({"data":gateway.client_token.generate()})

ajax json post request to flask

I am struggling to send a ajax post request but cannot figure out where i am going wrong, i have this form which i submit with js and along with that form i want to send the id of a div:
<script type="text/javascript">
$(document).ready(function() {
$('input[type=radio]').on('change', function() {
$(this).closest("form").submit();
var poll_id = $(this).closest("div").attr("id");
var data = {poll_id};
console.log(JSON.stringify(data));
$.ajax({
url: '/poll',
type: 'POST',
data: JSON.stringify(data),
contentType: 'application/json',
dataType: 'json'
}, function(data) {
console.log(data);
});
});
});
</script>
and in flask i try to request it with request.get_json() but keep getting error 400, the form and db.commit() works fine:
#app.route('/poll', methods=['GET', 'POST'])
def poll():
polltodb = pollingresult(request.form['points'])
session['points_session'] = request.form['points']
db.session.add(polltodb)
db.session.commit()
data = request.get_json()
print data
but the get_json() fails.
$(this).closest("form").submit(); tells your html page to submit the form. If any javascript after that line even executes you'd be making a separate XHR request (e.g. 2 requests, the data would never be in the same request using this approach). To accomplish what you're trying to do I'd take a different approach:
Add a hidden element to your form. e.g. <input type="hidden" name="poll_id" id="myHiddenField">
Update your javascript:
<script type="text/javascript">
(function(){
$('input[type=radio]').on('change', function () {
$('#myHiddenField').val($(this).closest("div").attr("id"));
$(this).closest("form").submit();
});
});
</script>
Then, access the data through the form as you normally would and don't worry about get_json()

How to redirect to an external url with parameters and POST method?

I want save form data before submit to action url in flask
<form action="" method="POST">
<input type="hidden" name="PAYEE_ACCOUNT" value="U1234567">
<input type="hidden" name="PAYEE_NAME" value="Name">
<input type="text" name="PAYMENT_AMOUNT">
<input type="submit" name="PAYMENT_METHOD" />
</form>
I can submit this form, but i want save form data before submit
View:
#mod.route('/payment/', methods=['GET', 'POST'])
def payment():
if request.method != "POST":
return render_template('form.html')
form = request.form
form_data = {'PAYEE_ACCOUNT': form['PAYEE_ACCOUNT'],
'PAYEE_NAME': form['PAYEE_Name'],
'PAYMENT_AMOUNT' : form['PAYMENT_AMOUNT']
}
# Save Data
import urllib
params = urllib.urlencode(form_data)
url = 'http://www.example.com'
return redirect(url, params)
Please help me
Sending a 307 status code instead of 302 should tell the browser to preserve the used HTTP method and thus have the behavior you're expecting. Your call to redirect would then look like this:
#mod.route('/payment/', methods=['GET', 'POST'])
def payment():
if request.method != "POST":
return render_template('form.html')
form = request.form
form_data = {'PAYEE_ACCOUNT': form['PAYEE_ACCOUNT'],
'PAYEE_NAME': form['PAYEE_Name'],
'PAYMENT_AMOUNT' : form['PAYMENT_AMOUNT']
}
# Save Data
url = 'http://www.example.com'
return redirect(url, code=307)
You need to use flask.redirect
flask.redirect(location, code=302)
Return a response object (a WSGI application) that, if called,
redirects the client to the target location. Supported codes are 301,
302, 303, 305, and 307. 300 is not supported because it’s not a real
redirect and 304 because it’s the answer for a request with a request
with defined If-Modified-Since headers.
Parameters:
location – the location the response should redirect to.
code – the redirect status code. defaults to 302.
Sample code:
import os
from flask import Flask,redirect
app = Flask(__name__)
#app.route('/')
def hello():
return redirect("http://www.example.com", code=302)
if __name__ == '__main__':
# Bind to PORT if defined, otherwise default to 5000.
port = int(os.environ.get('PORT', 5000))
app.run(host='0.0.0.0', port=port)
see the documentation on flask docs.
I've solved this problem by using JavaScript.
First, sending the data to server.
JavaScript code:
<script type="text/javascript">
var $SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
$(function() {
$('#PAYMENT_METHOD').bind('click', function() {
$.getJSON($SCRIPT_ROOT +'/credit/save_transaction', {
PAYMENT_ID: $('input[name="PAYMENT_ID"]').val(),
PAYMENT_AMOUNT: $('input[name="PAYMENT_AMOUNT"]').val(),
SUGGESTED_MEMO: $('input[name="SUGGESTED_MEMO"]').val()
}, function(data) {
if (data.result == 'ok') {
$('#form_payment').submit();
}
});
return false;
});
});
</script>
Then, saving the data and returning result.
View code:
#mod.route('/save_transaction', methods=['GET', 'POST'])
def save_transaction():
follow_num = request.args.get('PAYMENT_ID')
amount = request.args.get('PAYMENT_AMOUNT')
memo = request.args.get('SUGGESTED_MEMO')
#Save Data
return jsonify(result='ok')

Categories