I'm trying to send some data from Javascript to Django through ajax.
Here is my JS code:
var json_name = {'name': 123}
$.ajax({
method: 'POST',
url: 'my url',
contentType: "application/json",
headers: {
'Content-Type':'application/json',
'X-CSRFToken': "{{ csrf_token }}"
},
data: JSON.stringify(json_name),
success: function (data) {
//this gets called when server returns an OK response
alert("it worked!");
},
error: function (data) {
alert("it didnt work");
}
});
Here is my Views.py:
def myview(request):
if request.is_ajax():
request_data = request.body
# data = json.loads(request.body)
print(request_data)
# print(data)
return render(request, 'candidate/view.html')
else:
return render(request, 'candidate/view.html')
I get the output as b''
When I try to include these lines:
data = json.loads(request.body)
print(data)
I get this error:
TypeError: the JSON object must be str, not 'bytes'
I took some reference from here
Can someone help me with this? If you need any additional information to solve this, I'll be happy to share.
After losing half the hair on my head, I solved it in the following way:
views.py:
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
def myview(request):
if request.is_ajax():
if request.method == 'POST':
data = request.POST.get('senddata')
print(data)
return render(request, 'candidate/view.html')
else:
return render(request, 'candidate/view.html')
my JS code:
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
$.ajax({
type: 'POST',
url: 'my url',
// contentType: "application/json",
// headers: {
// 'Content-Type':'application/json',
// 'X-CSRFToken': "{{ csrf_token }}"
// },
dataType: "json",
data: {
senddata: JSON.stringify(json_name),
},
// data: json_name,
success: function (data) {
//this gets called when server returns an OK response
alert("it worked!");
},
error: function (data) {
alert("it didnt work");
}
});
When I run it, it shows it didnt work but I can see the output in my terminal i.e The data was passed.
I tried including the csrf token in the ajax request but it failed. Therefore I used csrf_exempt in my views.
This might be a dirty way of doing things, but it works for now. If anyone has a neat and better answer please post it here!!
I've written a basic testcase on Django 1.11 with Python 3.6 and Python 2.7.
I have been using the following template file to test:
<button>Send data</button>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
$('button').on('click', function(event) {
var data = { name: 123 };
$.ajax({
method: 'POST',
url: '',
contentType: 'application/json',
headers: {
'X-CSRFToken': '{{ csrf_token }}',
},
data: JSON.stringify(data),
success: function() {
console.log('Success!');
},
error: function() {
console.log('Error...');
},
});
});
</script>
And the following route, which delivers the template file and prints any AJAX data:
from django.http import response
from django.shortcuts import render
import json
def index(request):
if request.is_ajax():
request_body = request.body
data = json.loads(request_body)
print(data)
return render(request, 'stackoverflowhelp/index.html')
I've not been able to reproduce the issue.
However, having done more research I found that the json.loads method in Python 3.6 supports bytes objects, while the documentation for Python 2.7 json.loads suggests it only supports string types. While the error you've posted reflects this, I've attempted to make this generate the same error as you're seeing but have had no success.
As you can see, I've not had to whitelist the method from CSRF protection. Based purely on the error you've provided, calling decode on request.body may work:
def index(request):
if request.is_ajax():
request_body = request.body.decode("utf-8")
data = json.loads(request_body)
print(data)
return render(request, 'stackoverflowhelp/index.html')
Related
I am trying to post a JSON object from my client side Javascript to my Django View.
I receive a "500 (Internal Server Error)" When attempting to Post. Does this have to do with the CSRF token? And how can I get around this?
My AJAX
$.ajax({
type: 'POST',
dataType: 'json',
url: '/demo/saved/',
data: {'data': JSON.stringify(finalSelection)},
success: function() {
console.log("Success")
}
});
views.py
def show(request):
data = json.loads(request.POST.get('data', ''))
context = {
'data': data
}
return render(request, 'bill/saved.html', context )
urls.py
urlpatterns = [
path('bill/', views.bill_view, name = 'bill-view'),
path('saved/', views.show, name = 'selected-view'),
]
Appreciate any help!
Assuming its really the CSRF problem you mentioned, since you didn't post the 500 error output, you can simply add the csrf token to your data that is sent in POST request:
$.ajax({
...
data: {
'data': JSON.stringify(finalSelection),
'csrfmiddlewaretoken': '{{ csrf_token }}'
},
...
});
I'm receiving JSONdecode error when sending the POST request from ajax to django views.py. The POST sends an array of json. The data from this POST will be used to create the model. Appreciate for any hints.
Error:
Exception Type: JSONDecodeError at /order-confirmation
Exception Value: Expecting value: line 1 column 1 (char 0)
Request information:
USER: ledi12
GET: No GET data
POST: No POST data
FILES: No FILES data
AJAX Request:
var new_array = JSON.stringify(array)
$.ajax({
url: 'http://localhost:8000/order-confirmation',
type: 'POST',
data: '{"array":"' + new_array+'"}',
processData: false,
contentType: "application/json",
dataType: "json",
headers: {"X-CSRFToken":'{{ csrf_token }}'},
success: function (result) {
console.log(result.d);
},
error: function (result) {
console.log(result);
}
});
Views:
#csrf_exempt
def order_confirmation(request):
if request.method == 'POST':
data = json.loads(r"request.body").read()
print(data)
return HttpResponse(status=200)
else:
return render(request, 'main_templates/order_confirmation.html')
The reason you are getting this error is because the JSON library is not able to properly compile the string. There are a couple of things that your code needs to change. Remove 'r' character which is near request.body(). There is no need for 'read()' function in json.loads(). You can preprocess your array into a string and once done, and pass it to ajax. The data field will only have the string. So the ajax code field should look like
data: new_array
For my single page web app, I need to:
Send a json from .js to flask (DONE)
Run the input through a python function - getString() and get a str output (DONE)
Send the str output back to the .js file (PROBLEM)
Here is the flask app:
#app.route('/',methods =['GET','POST'])
def index():
req = json.dumps(request.get_json())
if request.method == 'POST':
result = getString(req) #Function outputs a string
return jsonify(result)
else:
print('Not Received')
return render_template('index.html')
if __name__ == '__main__':
app.run()
The problem is that the jsonify(result) is not being sent probably due to the request.method == 'POST' switching to else when jsonify is called. Is there any way to fix my code to send the str output to the .js?
Here is the .js:
//To send info to flask
document.querySelector('#generate').addEventListener('click',function() {
var json_inputs = JSON.stringify(inputs);
$.ajax({
type: "POST",
contentType: "application/json;charset=utf-8",
url: "/",
traditional: "true",
data: json_inputs,
dataType: "json"
});
})
//To receive from Flask
$.ajax({
url: "/",
type: 'GET',
success: function(data) {
console.log(data);
}
});
I think you've misunderstood what GET and POST are, GET is a request that only fetches something from the back end without a message body but a POST can send a body and recieve something.
try this instead:
document.querySelector('#generate').addEventListener('click',function() {
var json_inputs = JSON.stringify(inputs);
$.ajax({
type: "POST",
contentType: "application/json;charset=utf-8",
url: "/",
traditional: "true",
data: json_inputs,
dataType: "json",
success: function(data) {
console.log(data);
}
});
})
I am using ajax to POST a JSON string to Python Flask but get the following error:
Error
This is my JavaScript:
$.ajax({
type: 'POST',
url: window.location.href,
data: JSON.stringify(questionObj0),
dataType: 'json',
contentType: 'application/json; charset=utf-8'
}).done(function(msg) {
console.log(msg);
});
And this is my Python:
#app.route('/test', methods=['GET', 'POST'])
def test():
question = request.get_json()
question1 = json.loads(question)
print (question)
return render_template('test.html')
Using print(question) yields the following output (same output when tested in JavaScript using browsers console):
{'questionNumber': 1, 'question': 'Convert 10110001 to decimal', 'answer': 177, 'userAnswer': 'blank'}
From what I understand, the output should be a string and therefore padded with quotation marks.
Has anyone come across anything similar/know how to fix the issue?
Flask's request.get_json() returns a dict object from the JSON data supplied in the request, so you don't need to call json.loads on it again.
app.py
#app.route('/', methods=['GET'])
def index():
return render_template('index.html')
#app.route('/test', methods=['POST'])
def test():
question = request.get_json()
print(question['question'])
return ''
templates/index.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
var questionObj0 = {'questionNumber': 1, 'question': 'Convert 10110001 to decimal', 'answer': 177, 'userAnswer': 'blank'};
console.log(JSON.stringify(questionObj0));
$.ajax({
type: 'POST',
url: '{{ url_for('test') }}',
data: JSON.stringify(questionObj0),
dataType: 'json',
contentType: 'application/json; charset=utf-8'
}).done(function(msg) {
console.log(msg);
});
</script>
I am writing my first project in Django where I now want to make an Ajax request using jQuery to get some data. The problem is that the Ajax request returns:
GET http://localhost:8000/ajax/teams_for_issue/?medIssue=MI6 404 (Not Found)
I am rather certain that the problem is with the URL, and I have gotten the URLs wrong several times before in this project. My Ajax code looks as follows:
var medIssue = _this.issueSelector.val();
$.ajax({
url: '/ajax/teams_for_issue/',
data: {
'medIssue': medIssue
},
dataType: 'json',
success: function(data) {
_this.setTeams(data.teams)
}
});
This is the Django function that I want to send the answer:
def teams_for_issue(request):
medIssue = request.GET.get("medIssue", none)
teams = Team.objects.filter(has_competence=medIssue)
data = {
"teams":teams
}
return JsonResponse(data)
I have defined the following URL
url(r'newpatient/', views.newpatient, name='newpatient'),
url(r'ajax/teams_for_issue/', views.teams_for_issue, name='teams_for_issue'),
Any help on where I go wrong would be much appriciated :)
define type in your ajax request.
$.ajax({
url: '/ajax/teams_for_issue/',
type: "POST",
data: {
'medIssue': medIssue
},
dataType: 'json',
success: function(data) {
_this.setTeams(data.teams)
}
});
also your view should read data from request.POST
def teams_for_issue(request):
medIssue = request.POST.get("medIssue", none)
teams = Team.objects.filter(has_competence=medIssue)
data = {
"teams":teams
}
return JsonResponse(data)