Django parsing arguments - python

I'm using an AJAX call to get data from the server:
$.ajax({
type: 'POST',
url: '/simple/gd/',
dataType: 'json',
data: {t : "PL"},
success: function(data) {
var newd = data['t'];
alert('Load was performed: ' + newd);
}
});
On the server, urls.py is:
(r'^simple/gd/(?P<data>.*)$', 'simple.views.getData'),
The url that's getting to the server is http:/localhost/simple/gd/?t=PL
But for some reason, I can't make getData(request, data) to be called with "?t=PL" or with "t=PL" as 'data' parameter. 'data' is always empty.
What am I doing wrong?

If you use type: 'POST' then the data doesn't get appended to the URL as a query string.
Instead, it is included in the request object's POST dictionary.
So in order to pass something back that fires your alert you need to render a string that can be interpreted as json data something along the lines of:
(r'^simple/gd/$', 'simple.views.getData'),
def getData(request):
posted_t = request.POST['t']
# Do some stuff with posted_t
server_side_var = "Yay"
return HttpResponse(u"{t:%s}" % server_side_var)

That's because t=PL is not part of the path, it's the query string (the path, roughly speaking, is the bit before the ?, the query string is the bit after the ?).
Personally, I'd recommend changing your urls.py as follows:
(r'^simple/gd/$', 'simple.views.getData'),
Then, adjust your view function from something like:
def getData(request, data):
print data
to something like:
def getData(request):
print request.GET.get('t', None)

Related

I don't know the cause and solution of keyerror

I'm a beginner.
What I used was flask and pymongo.
If you press the button, it's "Like". It should be +1, but there is a key error at the bottom.
My python route code:
#app.route('/api/like', methods=['POST'])
def like_movie():
title_receive = request.form['title_give']
movie = db.toytoy.find_one({'title': title_receive})
current_like = movie['like']
new_like = current_like + 1
db.toytoy.update_one({'title': title_receive}, {'$set': {'like': new_like}})
return jsonify({'msg': 'like!'})
This is how I POST from JS
function like_movie(title) {
$.ajax({
type: 'POST',
url: '/api/like',
data: {title_give: title},
success: function (response) {
console.log(response)
alert(response['msg']);
window.location.reload();
}
});
}
I get an exception as below:
werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
KeyError: 'title_give'
What I want is if it's 'like_btn'. If you press the button, it becomes +1.
The base problem in what you did is not respecting Content-type. From front JS, you are making a POST with JSON object. Which makes the request to have a content type of application/json.
In backend code, you use request.form which expects the request to be in the form encoded types (like application/x-www-form-urlencoded, multipart/form-data) etc.
So, you need to read the JSON content in backend, instead of reading from a form which is not available. Like below:
ui_req = request.get_json()
title_receive = ui_req['title_give']
And then parse other structures accordingly.

Django: Encoding problem on production environment

The data is stored in a dataframe as "S\u00c3o Miguel", but the data is returned from template as "S%C3o Miguel", and Python can't find it on the dictionary. How can I solve this?
I developed an application that gets data (as well as the labels) from the database and plots them on charts using the Highcharts library.
When the user clicks on one of the bars of the charts, the label of it is sent back to the server, which returns some values.
The problem is: when the data is first loaded from the database, it is stored in memory in a dataframe, where "S\u00c3o Miguel" is one of the values, but when the user clicks on a chart and the JQuery request is made to the server, it is sent back as "S%C3o Miguel". Due to this, the code can't find this key on the dataframe in the memory.
I've tried to encode the string as UTF-8 with encodeuricomponent on JavaScript prior to sending it back to the server, but no success.
The template already has the tag.
def getFromDatabase():
[...]
wfarm_names = pd.read_sql(query, engine) #Gets the data from the database
return (list(wfarm_names['CL_NAME'].unique())) #Returns a list with all the keys. The value that causes the problem is returned as 'S\u00c3o Miguel'
def getData(request, cluster):
#In this case, cluster is returned from screen as 'S%C3o Miguel'
wfarm_names = list(general_frame[general_frame['CL_NAME'] == cluster]
#problem occurs here
The JQuery request is bellow:
$.ajax({
url: "http://127.0.0.1:8000/monitors/turbine-getter/" + cluster + "/",
data: {
csrfmiddlewaretoken: "{{ csrf_token }}",
},
dataType: "json",
success: function(data){
window.maxmin_vals = data.maxminvals;
cont.style.display = "inline-block";
pb.style.display = "none";
window.pointsDict = {};
window.current_buffers = data.latlong;
window.current_cluster = cluster;
)
},
error: function (rs, e) {
alert('Sorry, try again.');
}
});
It looks like jQuery is encoding the url, you can decode like this:
>>> from urllib import parse
>>> decoded = parse.unquote(url)

Python Flask - request.json returns None Type instead of json dictionary

I'm writing a very simple demo webapp, and I can't seem to pass a json object from js to python using ajax.
I've tried a number of suggestions from people on so with similar problems, such as using .get_json() instead of .json, passing the object without using JSON.stringify in the javascript, etc.
Any idea what piece I'm missing here?
Javascript
var run_method = function(){
var data1 = {"word":"hello"}
console.log("Before " + data1);
$.ajax({
url : "/examplemethod",
type : "POST",
data : data1//JSON.stringify(data1)
})
.done(function(data){
var data = JSON.parse(data);
console.log(data);
});
}
Python
#app.route("/examplemethod", methods=['POST', 'GET'])
def example_method():
global data
if request.method == 'POST':
print request
data = request.json
print "data", data
return "after "+ data["word"]
Every variation I have tried of this gives a 500 Error, and
TypeError: 'NoneType' object has no attribute 'getitem'
Obviously, that is because data is supposed to be an dictionary/json, not None. But how to I get it to return as a dictionary?
Because you are not sending JSON, to the flask app (see this and this). Your current code results in a standard urlencoded form post. Which in turn results in an entry being populated in request.form
request.form.get('word')
Switch to a json post as per the guidelines in the above Q&As to access the data through request.json.
the data is likely not flowing to json if you are getting None, so you should jsonify the data. It will be coming in in the form of form.
from flask import jsonify
#app.route("/examplemethod", methods=['POST'])
def example_method():
data = jsonify(request.form).json
print(data) #will be in the form a json dict
return data['foo-key'] #can retrieve specific items with their key-pairs

Django & Ajax: How can I create a csv file download from posting data through AJAX to Django?

I'm trying to allow the click trigger to do some backend dynamic csv creation, and then return it back to the user as a csv download file. I guess I'm not sure how I should write out the return statement other than just putting return response. I'v come across some other posts saying that I would need to set my url to a hidden iframe?? Not sure what this means though. Any tips?
Ajax looks like this:
$('#download-maxes').on('click', function(){
$.ajax({
type: "POST",
url: "{{request.path}}download/",
dataType: 'json',
async: false,
data: JSON.stringify(workouts),
success: function(workoutData) {
console.log(workoutData);
},
error:function(error){
console.log(error);
}
});
});
And my django view looks like this:
def download(request):
#(... a lot of mongo stuff here & other things defined)
workouts = json.load(request.body)
response = HttpResponse(content_type='text/xlsx')
response['Content-Disposition'] = 'attachment; filename="team_maxes.xlsx"'
writer = csv.writer(response)
writer.writerow(['Name', 'Date', 'Workout', 'Max'])
for member in team_members.all():
for wo in workouts:
wo_data = db.activity_types.find_one({"name": wo["name"]})
best_wo = db.activity.find_one({"u_id": member.user.id, "a_t": str(wo_data["_id"]), "is_last": 1}) or 0
member_name = member.user.first_name + ' ' + member.user.last_name
try:
max_stat = best_wo["y_ts"]
except:
max_stat = 0
try:
date = best_wo["e_d"]
except:
date = ""
workout_name = wo_data["name"]
writer.writerow([member_name, date, workout_name, max_stat])
return response
You don't need to use ajax. Since you are POSTing some json data to your view, just make a form with a hidden text input, and set it's value to the json data. Then make a regular submit button in the form.
When the form gets submitted, and the server responds with Content-Disposition: attachment; filename="team_maxes.xlsx", your browser will automatically trigger a download.
If you decide to go this route, Keep in mind:
You are using a regular html form now, with the POST method, so you must remember to use django's {% csrf_token %} tag inside of it.
You will probably have set the input's value to your json string, right before submitting the form.
Your workouts json gets sent in a form input. So, assuming you named your input "workouts", in your view you would do something like:
workouts = json.loads(request.POST.get('workouts'))
Plus a bunch of error checking, of course.

Parsing json object sent with Ajax GET method in Django

I have created an Ajax request which should be processed by Django:
var tracks = [{'artist':'xxx', 'track':'yyy', 'duration':100},
{'artist':'xxx', 'track':'yyy', 'duration':100},
{'artist':'xxx', 'track':'yyy', 'duration':100}];
$.ajax({
type: 'GET',
url: ROOT_URL + '/snv/',
data: {tracks: tracks},
dataType: 'json'
}).done(function (data) {
// do something
}).fail(function (data) {
// do something else
});
and I have a Python function to retrieve that data:
def snv(request):
for track in request.GET:
print track
But this function prints something like:
tracks[1][artist]
tracks[0][track]
tracks[0][duration]
tracks[2][artist]
tracks[1][track]
tracks[1][duration]
tracks[2][duration]
tracks[0][artist]
tracks[2][track]
If I print request.GET I get this:
<QueryDict: {u'tracks[1][artist]': [u'Artist 02'], u'tracks[0][track]': [u'title 00'], u'tracks[0][duration]': [u'202'], u'tracks[2][artist]': [u'Artist 04'], u'tracks[1][track]': [u'title 02'], u'tracks[1][duration]': [u'506'], u'tracks[2][duration]': [u'233'], u'tracks[0][artist]': [u'Artist 00'], u'tracks[2][track]': [u'title 04']}>
How to process my object properly?
You can solve it by using json encoding:
encode in javascript
data: {tracks: JSON.stringify(tracks)}
decode in the view
tracks = json.loads(request.POST.get('tracks'))
This way you avoid 3rd party parser :)
Ok, I solved it like this:
changed my Ajax request from GET to POST,
followed this to acquire CSRF_token,
used this parser to parse my object,
and finally changed my Python function:
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
def startNewVoting(request):
from querystring_parser import parser
p = parser.parse(request.POST.urlencode())
for key, track in p['tracks'].iteritems():
print track
# save to db...

Categories

Resources