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()
Related
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
I'm using ajax, python, Django, HTML, and javascript for my project.
I'd like to know, if there is a p in my HTML file like,
<p class='text_box', id='tbox'>
{{ text_variable_from_python }}
</p>
<input class='input_box', id='ibox', type='text'>
And if I'd input some text into the input box, make a simple ajax request with the "text" variable and get an output from the server, which I would update on the views.py as,
def main(request):
if request.method == 'POST':
new_text = request.POST['text']
context = {'text_variable_from_python': new_text}
else:
context = {'text_variable_from_python': 'You can change me!'}
print(context)
return render(request, 'Main.html', context=context)
My question is, how do I send the data dynamically from the server to appear on client's webpage using ajax and python in between the two?
Using my method, I can only see "You can change me!" on the webpage or nothing at all. No matter how many differing prompts I give, further changes do not show on the webpage.
EDIT:
My ajax code for sending the variable.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
function update_dialogue() {
$.ajax({
type: "json",
url: "update_text",
success: function(data) {
document.getElementById("tbox").value = data['text_variable_from_python'];
}
});
}
My ajax code for recieving the variable.
<script>
function getInputValue() {
let inputVal = document.getElementById("ibox").value;
document.getElementById("ibox").value = '';
$.ajax({
type:'POST',
url: 'main',
data: {csrfmiddlewaretoken: "{{ csrf_token }}",
'text': inputVal,}
});
}
</script>
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.
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.
I've been struggling on this for a couple days. I've read through many posts, blogs, and watch video demo on Django projects, but nothing quite answers my problem.
I have a Django webapp that uses a Python API to connects to a third-party service to analyze text data. The user writes into a text area, presses the button, then the text is sent to the service which returns a list of JSON objects. The API call to this service is a Python function. I'm trying to use Ajax to make an async call to the Python function using the text data as a param when the button is pressed.
I'm not at this time trying to invoke my third-party service, yet. I'm just trying to see if I can get a response from Python sending input and receiving output.
Most of the examples I've found involve creating a form and submitting it so the Django framework automatically calls it's Python functions. A form is not exactly what I'm trying to build, nor am I wanting to proceed to a new page to see the results or refresh the current one.
<!-- index.html -->
<html>
<head>
<title>Test Data</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script>
document.getElementById("Button").addEventListener('click', analyzeText());
function analyzeText(){
var text = document.getElementById('text-to-analyze').value;
$ajax({
type: "POST",
url: "/models.py", /* Call python function in this script */
data: {param: text}, /* Passing the text data */
success: callback
});
}
function callback(response){
console.log(response);
}
</script>
</head>
<body>
<textarea id="text-to-analyze" rows="12" cols="100"></textarea><br>
<button id="button" value="Analyze"/>
</body>
</html>
# models.py
from django.db import models
# Function I want to call from Ajax
def testcall():
return 'test successfull'
EDIT:
I almost have it working. I'm just getting syntax errors with ajax I can't figure out.
Could not parse the remainder: ' 'ajax-test-view'' from 'url 'ajax-test-view''
EDIT
I fixed all the syntax errors but now I'm getting 404 errors when trying to execute the target python script. I now understand how url and pathing works in Django, but using Kostadin Slavov's solution, how can I do this without routing to a specific html?
In the ajax, I'm setting the url like this:
url: '{{ 'ajax-test-view' }}',
And in my python I have the url pattern set like this:
path(r'^django-app/$', views.testcall, name = 'ajax-test-view'),
It seems like the variable in the ajax url points to the name field in the url pattern, but that also seems to be the name of a specific html file to render(?) Or is it the name of the py function?
When I click my button the ajax sends a command to http://localhost:8000/what-ever-the-name-field-is-in-the-url-pattern and I get a 404 from it. Is the framework trying to load a page or does it mean it can't find my python file?
Derp... It's important to know that url: '{{ 'ajax-test-view' }}', is the url address ajax will request and Django's url dispatcher intercepts it to do something else only if the path matches perfectly.
FINAL EDIT
Got it working. A couple things I changed in Kostadin Slavov's solution:
# urls.py
urlpatterns = [
url(r'^$', views.index, name = 'index'),
path('my-ajax-test/', views.testcall),
]
<!-- index.html -->
<script>
....
var text = "test successful";
$.ajax({
type: "POST",
url: '{{ 'my-ajax-test/' }}',
data: { csrfmiddlewaretoken: '{{ csrf_token }}', text: text },
success: function callback(response){
console.log(response);
}
});
</script>
# views.py
def testcall(request):
return HttpResponse(request.POST['text'])
in the urls.py you create an url
path('my-ajax-test/', views.myajaxtestview, name='ajax-test-view'),
then your ajax should loook like
pay attention to the csrf_token otherwise will send you an error
$ajax({
type: "POST",
url: '{{ url 'ajax-test-view'}}',
data: {csrfmiddlewaretoken: '{{ csrf_token }}',
text: "this is my test view"}, /* Passing the text data */
success: function(response){
alert(response);
}
});
in views.py
def myajaxtestview(request):
return HttpResponse(request.POST['text'])
Summary:
you need to create the url in your urls.py which leads to your views.py
then the view gets the data that you've sent in the request.POST in the request you have plenty of data you can find more about it here.
in your case you are more interested in request.POST it's a python dictionary
so you pick the parametre that you have send and work with it
you may play with it like return HttpResponce('test'+ request.POST['text'])
If you want to get something from models.py let's say you data that you sent from the js is {object_type: hammer}
def myajaxtestview(request):
look_for = request.POST['object_type']
#lets say you have model Items
my_items= serializers.serialize('json', Items.objects.filter(object_type=look_for))
return JsonResponse(my_items)
Use AJAX
Add this in your html file
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
Then use this in your js file
$.ajax({
type: "POST",
url: "Your defined route in urls.py file", #then in your views.py you can define your operations
data: {
csrfmiddlewaretoken: '{{ csrf_token }}',
text: your_input
}, /* Passing the text data */
success: function(response) {
alert(response); #response form your request
}
});
You have to receive this post request in your views.py file as:
request.POST.get("key")
What you are trying is a well known problem. When you do ajax request to the server , the server responds with some data or may be renders a template.
For this request - response cycle to work, you will have to create a mapping of the url to the controller logic. You will have to create a url and a python function mapping in urls.py.
The python function will be in views.py. Now when you request for that url with the given method(POST or GET), it will call the mapping function and return the result.
After reading the question edits and the different answers, this is
what worked for me (doesn't include imports):
File: urls.py
#urls.py
urlpatterns = [
path('', views.index, name = 'index'),
path('my-ajax-test/', views.testcall),
]
File: index.html
#index.html
<html>
<head>
<title>Test Data</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script>
function analyzeText(){
var text = document.getElementById('text-to-analyze').value;
$.ajax({
type: "POST",
url: '{{ 'my-ajax-test/' }}',
data: { csrfmiddlewaretoken: '{{ csrf_token }}', text: text },
success: function callback(response){
/* do whatever with the response */
alert(response);
}
});
}
</script>
</head>
<body>
<textarea id="text-to-analyze" rows="12" cols="100"></textarea><br>
<input type="submit" id="button" value="process" onclick="analyzeText();">
</body>
</html>
File: views.py
#views.py
def index(request):
return render(request, 'vote/index.html')
def testcall(request):
#Get the variable text
text = request.POST['text']
#Do whatever with the input variable text
response = text + ":)"
#Send the response
return HttpResponse(response)
I struggled with this issue for a day or two. Here's what solved my problem.
EDIT: I also needed to download the full version of jquery to get the ajax request working.
HTML
In your HTML you need to add {% csrf_token %} to your form
<form id="your_form">
{% csrf_token %} //include the csrf_token line in your form
<div>
<input type="submit" value="blah blah blah">
</div>
</form>
script.js
For your java script code add this function to get the csrf cookie.
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;
}
Next you need to add the csrf token into your ajax request as follows.
var csrftoken = getCookie('csrftoken');
$.ajax({
type: "POST",
url: '/my-url/', --your url here
data: { csrfmiddlewaretoken: csrftoken, text: "your text data here" },
success: function callback(response){
console.log(response);
}
});