I have a VERY simple HTML form with just one <input type='text'> field, an email address, that I need to pass back to a Python script via AJAX. I can't seem to receive the value on the other end. (And can all the JSON encoding/decoding be avoided, since there's just one field?)
Here's the code:
from flask import Flask, render_template, request, json
import logging
app = Flask(__name__)
#app.route('/')
def hello():
return render_template('index.htm')
#app.route('/start', methods=['POST'])
def start():
# next line outputs "email=myemail#gmail.com"
app.logger.debug(request.json);
email = request.json['email'];
# next line ALSO outputs "email=myemail#gmail.com"
app.logger.debug(email);
return json.dumps({ 'status': 'OK', 'email': email })
if __name__ == "__main__":
app.run()
And the Javascript that sends the AJAX from the HTML side--
$( "form" ).on( "submit", function( event ) {
event.preventDefault();
d = "email=" + $('#email').val(); // this works correctly
// next line outputs 'sending data: myemail#gmail.com'
console.log("sending data: "+d);
$.ajax({
type: "POST",
url: "{{ url_for('start') }}",
data: JSON.stringify(d),
dataType: 'JSON',
contentType: 'application/json;charset=UTF-8',
success: function(result) {
console.log("SUCCESS: ");
// next line outputs 'Object {email: "email=myemail#gmail.com", status: "OK"}'
console.log(result);
}
});
});
JSON.stringify is used to turn an object into a JSON-formatted string, but you don't have an object, just a string. Try this:
var d = { email: $('#email').val() };
JSON.stringify(d) will now turn that into a JSON-formatted string:
{email: "myemail#gmail.com"} which can be parsed by flask.
To do this without JSON:
var d = { email: $('#email').val() };
...
// AJAX
data: d,
success: ...
This will turn {email: "myemail#gmail.com"} into email=mymail#gmail.com and send that as body of the POST request. In Flask, use request.form['email'].
Related
I am trying to query the employee list based on parameter I send
through ajax call inside data, but it giving me an error (i want it
through GET req only )
Js ajax func
$(document).ready(function () {
$(".call_ajax").click(function () {
$.ajax({
url: "/employee_list",
type: "GET",
contentType: "application/json",
dataType: "json",
data: {
designation: "soft eng",
},
headers: {
"X-CSRFToken": csrftoken,
Authorization: my_token,
},
success: function (data) {
console.log(data);
},
error: function (xhr) {
//Do Something to handle error
console.log(xhr.error);
},
});
});
my view
#csrf_exempt
#api_view(['GET', 'POST', 'PUT', 'DELETE'])
#permission_classes([IsAuthenticated])
#authentication_classes([TokenAuthentication])
def employee_list(request):
if request.method == 'GET':
data_ = request.data['designation']
print(data_)
employees = Employee.objects.all()
students = Student.objects.all()
user = MyUser.objects.all()
serializer = EmployeeSerializer(employees, many=True)
serialized_sudents = StudentSerializer(students, many=True)
multi = {
'employees': serializer.data,
'students': serialized_sudents.data
}
# serializer2 = UserSerializer(user, many=True)
return JsonResponse(multi, safe=False)
error i am getting in browser
GET http://127.0.0.1:8000/employee_list/ 500 (Internal Server Error)
error in Django log
File "C:\Users\atif\PycharmProjects\CodePlatform\syntax_fight\api_\views.py", line 42, in employee_list
data_ = request.data['designation']
KeyError: 'designation'
request.data returns the parsed content of the request body.
This is similar to the standard request.POST and request.FILES
You can use request.GET.get('designation')
#csrf_exempt
#api_view(['GET', 'POST', 'PUT', 'DELETE'])
#permission_classes([IsAuthenticated])
#authentication_classes([TokenAuthentication])
def employee_list(request):
if request.method == 'GET':
data_ = request.GET.get('designation') # Here I made changes
print(data_)
employees = Employee.objects.filter(designation=data_) # Map parsed data with database field
students = Student.objects.all()
user = MyUser.objects.all()
serializer = EmployeeSerializer(employees, many=True)
serialized_sudents = StudentSerializer(students, many=True)
multi = {
'employees': serializer.data,
'students': serialized_sudents.data
}
# serializer2 = UserSerializer(user, many=True)
return JsonResponse(multi, safe=False)
or
You can override get_queryset method. As for query string parameters request.data holds POST data, you can get query string params through request.query_params
def get_queryset(self):
data = self.request.query_params.get('designation')
queryset = Model.objects.filter() # use whatever you want filter
return queryset
To know more about request.data and request.query_params, here is the link
Request parsing link
It is most probably because you are using GET, but the data resides in body. Have a look at this. To try to fix this, change your request method to POST:
$.ajax({
url: "/employee_list",
type: "POST",
...
I want to receive data from ajax, but I got "None" as my variable
class update(webapp2.RequestHandler):
def post(self):
print("data",self.request.POST.get('data'))
app = webapp2.WSGIApplication([
('/update', update)
], debug=True)
data= 3;
$.ajax({
url: "/update",
data: data, //data=3
type: "POST",
success: function( xml ) {
alert( "It worked!" );
},
});
i got: ('data', '') as result when i expected: "data '3'"
Edit: if possible, please keep the answer to just one line: like:
print("data",self.request.POST.get('data'))
Thanks to Beniamin H,the solution is simple.
data= {
'a':3 // I changed data to a dictionary
// edit:you don't need quotes for a, so, a:3 works also
}
$.ajax({
url: "/update",
data: data,
type: "POST",
success: function( xml ) { //more edit:xml is the data returned
alert( "It worked!" ); //from the webbapp you can name it what
//ever you want
//this gets data from the server
console.log(xml['a']) //prints out 3
},
});
class update(webapp2.RequestHandler):
def post(self):
data=self.request.POST.get('a')
print("data: "+data)
#edit: to return a data to javascript, make a dictionary like:
# data={
# 'a':3
# 'b':5 #you need quotes i think
# }
#and then write:
# self.response.write(data)
This prints out: data: 3
I used an ajax post request to send some variable from my javascript front end to my python back end. Once it was received by the back end, I want to modify these values and send them back to display on the front end. I need to do this all without refreshing the page.
With my existing code, returning the values to the front end gives me a 'null' or '[object object]' response instead of the actual string/json. I believe the formatting of the variables I'm passing is incorrect, but it's too complicated for me to understand what exactly I'm doing wrong or need to fix.
This is the javascript ajax POST request in my template. I would like the success fuction to display the new data using alert.
var arr = { City: 'Moscow', Age: 25 };
$.post({
headers: { "X-CSRFToken": '{{csrf_token}}' },
url: `http://www.joedelistraty.com/user/applications/1/normalize`,
data: {arr},
dataType: "json",
contentType : "application/json",
success: function(norm_data) {
var norm_data = norm_data.toString();
alert( norm_data );
}
});
This is my Django URLs code to receive the request:
path('applications/1/normalize', views.normalize, name="normalize")
This is the python view to retrieve the code and send it back to the javascript file:
from django.http import JsonResponse
def normalize(request,*argv,**kwargs):
norm_data = request.POST.get(*argv, 'true')
return JsonResponse(norm_data, safe = False)
You need to parse your Object to an actual json string. The .toString() will only print out the implementation of an objects toString() method, which is its string representation. By default an object does not print out its json format by just calling toString(). You might be looking for JSON.stringify(obj)
$.post({
headers: { "X-CSRFToken": '{{csrf_token}}' },
url: `http://www.joedelistraty.com/user/applications/1/normalize`,
data: {arr},
dataType: "json",
contentType : "application/json",
success: function(norm_data) {
var norm_data = JSON.stringify(norm_data);
alert( norm_data );
}});
I've observed that there's a difference between POST data being sent by a form and POST data being sent by this AJAX request. The data being sent through a form would be form-encoded whereas you are sending raw JSON data. Using request.body would solve the issue
from django.http import JsonResponse
def normalize(request):
data = request.body.decode('utf-8')
#data now is a string with all the the JSON data.
#data is like this now "arr%5BCity%5D=Moscow&arr%5BAge%5D=25"
data = data.split("&")
data = {item.split("%5D")[0].split("%5B")[1] : item.split("=")[1] for item in data}
#data is like this now "{'City': 'Moscow', 'Age': '25'}"
return JsonResponse(data, safe= False)
i am using ajax to fetch django model and get results
views.py
def browse_jobs(request):
keyword = request.GET.get('keyword', None)
company = Company.objects.filter(title__icontains=keyword)
data = serializers.serialize("json", company, fields=('title'))
return JsonResponse({'data':data,})
ajax request
$.ajax({
url: '/browse_jobs',
data: {
'keyword': keyword,
},
dataType: 'json',
success: function (data) {
if (data) {
console.log(data.title);
}
}
});
and i am getting this response from django
{"data": "[{\"model\": \"app.company\", \"pk\": 1, \"fields\": {\"title\": \"Facebook\"}}, {\"model\": \"app.company\", \"pk\": 2, \"fields\": {\"title\": \"Fabook\"}}]"}
my question is how i can access the title.
You here double serialized the value for the "data" key: first by the serializers.serialize(..) that constructed a string, and the you again serialize it (constructing an string literal), making it harder to obtain the elements.
We can prevent this, for examply by turning the JSON blob back into a vanilla Python object first:
from json import loads as json_loads
def browse_jobs(request):
keyword = request.GET.get('keyword', None)
company = Company.objects.filter(title__icontains=keyword)
data = serializers.serialize("json", company, fields=('title'))
return JsonResponse({'data': json_loads(data), })
Then the AJAX call will receive a JSON blob where "data" does not map to a string, but a list of subdictionaries, making it easier accessible.
Here there are two results for your query, you can print the first title with:
$.ajax({
url: '/browse_jobs',
data: {
'keyword': keyword,
},
dataType: 'json',
success: function (data) {
console.log(data.data[0].fields.title);
}
});
Currently I am using Flask and Jquery and getting a 500 Internal Server Error response in my console. When I post with Ajax to the url on flask, shouldn't it be able to be received? I don't understand why I am getting this error.
Jquery
$('.movie').click(function(){
console.log(this);
$(this).toggleClass('green blue').promise().done(function(){
if ($(this).html() == "Add Movie"){
$(this).html("Added");
}
});
id = $(this).val();
//get information from API
$.ajax({
url: "/profile",
dataType: 'json',
async: true,
data: {id: id},
success: function(data) {
}
});
Python/Flask
#app.route("/profile", methods = ["GET"])
def profile(id):
print("mydata is: ", request.args['id'])
if request.args.get:
print("this API is reached")
id = request.args.get['id']
url_movie = 'https://api.themoviedb.org/3/movie/{}?api_key=78cb6b67a99ce26e6d6619c617d9c907&language=en-US'.format(id)
r = requests.get(url_movie)
code = r.json();
return jsonify(code)
500 is a server error. There is something wrong with the request execution at server side only.