My save function is not working - I am new to Jquery - python

This is my first time with using jquery and I am trying to save a reply but it gives a successful message but it not actually but I can't see the reply that the system says it saved.
$(document).ready(function(){
$(".reply_open_modal").click(function(){
var id=$(this).parents("tr").children("td:eq(0)").text();
var name=$(this).parents("tr").children("td:eq(2)").text();
$("#reply_id").val(id);
$("#reply_name").text(name);
});
I think this part of my system works but iIam not sure and the purpose of this code is to send the reply message
$(document).on("click","#reply_btn",function(){
$(this).attr("disabled","disabled")
$(this).text("Sending Reply")
var id=$("#reply_id").val();
var message=$("#reply_message").val();
$.ajax({
url:'{% url 'admin_message_replied' %}',
type:'POST',
data:{id:id,message:message},
})
.done(function(response){
if(response=="True"){
alert("Sent")
}
else{
alert("Not Sent")
}
location.reload()
})
.fail(function(){
alert("Error in Sending Reply")
})
})
})
This is the function that saves the reply into my database but it not working:
#csrf_exempt
def admin_message_replied(request):
reply_id=request.POST.get("id")
reply_message=request.POST.get("message")
try:
messages = SendmessageAdmin.objects.get(id=reply_id)
messages.message_reply = reply_message
messages.save()
return HttpResponse("True")
except:
return HttpResponse("False")

Related

Django request.GET.get() returns None every two times

I'm trying to use some ajax request to echange between django views and the templates but i'm experiencing a strange behavior with the request.GET.
Django sends an error saying that the data in parameter of the json.loads(data) shouldn't be NoneType as the result of request.GET.get('selects') seems to be None; but if I try to debug this code, it seems that request.GET.get('selects') returns None every two times.
When requesting request.GET.get('selects') in the console, I get:
None the first time
and '[{"pk":"57226796-0960-428a-88aa-ba4120ad34b4"}]' the second time,
then None again
then '[{"pk":"57226796-0960-428a-88aa-ba4120ad34b4"}]' at the third attempt.
every odd attempt return None....
what do I wrong ?
views.py
class AjaxRenameView(View):
def get(self,request):
#import pdb; pdb.set_trace()
selects=request.GET.get('selects', None)
selects=json.loads(selects)
pks = [ pk['pk'] for pk in selects]
if len(pks)==1:
folder=Folder.objects.filter(pk=pks[0])
spotler=Spotler.objects.filter(pk=pks[0])
if folder:
form=FolderRenameForm(instance=folder)
title=_('rename folder')
elif spotler :
form=SpotlerRenameForm(instance=folder)
title=_('rename project')
context={'form':form,'title':title,'submit':_('rename'),'has_error':False}
html_form = render_to_string('includes/modal_form.html',
context,
request=request,
)
return JsonResponse({'html_form': html_form})
return JsonResponse({'has_error':True, 'message':_('an error has occured while renaming')}, safe=False)
def post(self,request):
pass
folder.js
//...
function ajaxAction(selects,url,next){
// when clicked on item of menu (rename, share, move...)
$.ajax({
type:"GET",
data:{'selects':JSON.stringify(selects),'next':next},
url: url,
dataType:"json",
beforeSend: function () {
$("#Modal .modal-content").empty();
},
success: function (data) {
$("#Modal .modal-content").html(data.html_form);
}
});//ajax
}//function ajaxAction
//...
console
(Pdb) request.GET.dict()
{'selects': '[{"pk":"57226796-0960-428a-88aa-ba4120ad34b4"}]', 'next': '/fr/wf/myfiles/'}
(Pdb) request.GET.get('selects')
(Pdb) request.GET.get('selects')
'[{"pk":"57226796-0960-428a-88aa-ba4120ad34b4"}]'
(Pdb) request.GET.get('selects')
(Pdb) request.GET.get('selects')
'[{"pk":"57226796-0960-428a-88aa-ba4120ad34b4"}]'
well I finally found it.
the click() event that triggered the ajax call was related to the href attribute of an element. And as I didn't halt the execution of the function, the link was activated and a call to the django view without parameters was send...
the ajax call with return false; or e.preventDefault();
I modified the ajax call a little bit :
function ajaxActionMenu(pk_list,url){
$.ajax({
type:'GET',
data:{'pk_list':JSON.stringify(pk_list)},
url: url,
dataType:'json',
success:function(data){
jQuery.each(data, function(index,value){
$("#Modal .modal-body .nav").append('<a class="nav-link" href="'+value["url"]+'">'+value["menuitem"]+'</a>');
});
},
complete: function(){
$("#Modal .modal-body .nav").on("click",".nav-link",function(e){
e.preventDefault(); // prevent the activation of the href link
var urlLink=$(this).attr("href");
ajaxAction(pk_list,urlLink);
$("#Modal").modal("show");
});
}
});
}

passing JSON data to django using AJAX

I am using python3.6 and Django 2.0.3 on Ubuntu 17.10. I'm a bit new to Django and trying to understand it. I have a table with some input fields in the html page where the users will enter data. My AJAX code below gets the data from the table rows and passes it to django view. CSRF is handled as per the django documentation as I have no form in my html.
Here is my AJAX code (using jQuery)
$(document).ready(function() {
var table = $('#example').DataTable();
$('button').click( function() {
var TableData = new Array();
$('#example tr').each(function(row, tr){
TableData[row]={
"id" : $(tr).find('td:eq(0)').text()
, "student_name" :$(tr).find('td:eq(1)').text()
, "marks" : $(tr).find('td:eq(2) input', this).val()
, "is_present" : $(tr).find('td:eq(3) select', this).val()
}
});
TableData.shift(); // first row will be empty - so remove
TableData = JSON.stringify(TableData);
alert(TableData);
$.ajax({
type: "POST",
url: "{% url 'result:ajax_update_result' %}",
dataType: 'json',
data: TableData,
success: function(msg){
alert(msg);
}
});
return false;
} );
});
Here is the result of the alert call in the above AJAX. The same data is passed to the djago view code which handles this AJAX call.
[{"id":"1","student_name":"Test Student","marks":"0.00","is_present":"1"},{"id":"2","student_name":"Test Student3","marks":"0.00","is_present":"1"}]
Below is my django view for the above AJAX call.
import json
def save_result(request):
table_data = json.dumps(request.GET.get('TableData'))
print(table_data)
return render(request, 'data/dummy.html', {'msg': 'Data Saved.'})
The django console prints null for the above print(table_data)
Please note: I used json.loads in the django view code and got a type error.
I am expecting the data from the AJAX call to be passed to the django function and the data printed in console as dictionary.
You should first stringify your JSON data:
$(document).ready(function() {
var table = $('#example').DataTable();
$('button').click( function() {
var TableData = new Array();
$('#example tr').each(function(row, tr){
TableData[row]={
"id" : $(tr).find('td:eq(0)').text()
, "student_name" :$(tr).find('td:eq(1)').text()
, "marks" : $(tr).find('td:eq(2) input', this).val()
, "is_present" : $(tr).find('td:eq(3) select', this).val()
}
});
TableData.shift(); // first row will be empty - so remove
alert(TableData);
$.ajax({
type: "POST",
url: "{% url 'result:ajax_update_result' %}",
dataType: 'json',
data: JSON.stringify({'TableData': TableData}),
success: function(msg){
alert(msg);
}
});
return false;
} );
});
And retrieve it from request.POST:
import json
def save_result(request):
table_data = json.loads(request.POST.get('TableData'))
print(table_data)
return render(request, 'data/dummy.html', {'msg': 'Data Saved.'})
Note I'm using json.loads since your data is now stringified.
EDIT: I just realized you were actually stringifying your TableData...however, you were trying to pull from a non-existent key TableData from request.GET. I believe my updated answer should work for you.

django saving messages to database via node server and socket.io

I have node server:
var http = require('http');
var server = http.createServer().listen(4000);
var io = require('socket.io').listen(server);
var cookie_reader = require('cookie');
var querystring = require('querystring');
var redis = require('redis');
var sub = redis.createClient();
//Subscribe to the Redis chat channel
sub.subscribe('chat');
//Configure socket.io to store cookie set by Django
io.use(function(){
io.set('authorization', function(data, accept){
if(data.headers.cookie){
data.cookie = cookie_reader.parse(data.headers.cookie);
return accept(null, true);
}
return accept('error', false);
});
io.set('log level', 1);
});
io.sockets.on('connection', function (socket) {
//Grab message from Redis and send to client
sub.on('message', function(channel, message){
socket.send(message);
});
//Client is sending message through socket.io
socket.on('send_message', function (message) {
values = querystring.stringify({
comment: message,
sessionid: socket.handshake.cookie['sessionid'],
});
var options = {
host: 'localhost',
port: 8000,
path: '/node_api',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': values.length
}
};
//Send message to Django server
var req = http.request(options, function(res){
res.setEncoding('utf8');
//Print out error message
res.on('data', function(message){
if(message != 'Everything worked :)'){
console.log('Message: ' + message);
}
});
});
req.write(values);
req.end();
});
});
When I send message it does not save in the database..
Here is my view for django:
#csrf_exempt
def node_api(request):
print "inside node"
try:
print "inside try"
session = Session.objects.get(session_key=request.POST.get("sessionid"))
print "first"
user_id = session.get_decode().get("_auth_user_id")
print user_id
user = User.objects.get(id=user_id)
Comments.objects.create(user=user, text=request.POST.get("comment"))
r = redis.StrictRedis(host="localhost", port=6379, db=0)
r.publish("chat", user.username + ": " + request.POST.get("comment"))
return HttpResponse("Everything worked :")
except Exception, e:
return HttpResponseServerError(str(e))
Whats wrong in here??
Can anyone guide me to right direction?
When I go to '/node_api/' url it says Session matching query doesnot exist..
My view for displaying message:
#login_required
def home(request):
print "entered"
comments = Comments.objects.select_related().all()[0:100]
return render(request, "index.html", locals())
When I submit the message its not saving to database neither displaying...
Thanx in advance??
If you are using python then why don't you try python way of doing realtime.
Try tornado with django. It supports socket.io..
You can code in python with no difficulty.
It doesn't mean javascript is not good but try do in python and have a look at tornado, redis, django. YOu will find your solution.

Decoding JSON with python using Appengine

I have the following code which retrieves values from a simple 3 input form:
//retrieves data from a form
var $form = $( this ),
prgname= $form.find('input[name="prg"]').val(),
startDate = $("#startdate").datepicker({ dateFormat: 'yy-mm-dd' }).val(),
endDate = $("#enddate").datepicker({ dateFormat: 'yy-mm-dd' }).val();
The following code sends the request to the server:
var request = $.ajax({
url: "/prg/",
type: "post",
data: JSON.stringify({prg: prgname, start:startDate, end:endDate}),
contentType: 'application/json',
dataType: 'json',
success: function() {},
error: function (jqXHR, textStatus, errorThrown){};
on the server end using python and webapp2 Im doing the following, (here is where I am unsure of things)
import json
class PrgHandler(webapp2.RequestHandler):
def post(self):
prg= cgi.escape(self.request.POST['prg'])
start_date = cgi.escape(self.request.POST['start'])
end_date = cgi.escape(self.request.POST['end'])
#some code to write to db here
....
#if successful return a success message
if success:
success_msg = [{'class': 'success', 'msg': 'Successfully saved to the database'}]
else:
success_msg = [{'class': 'error', 'msg': 'Could not saved to the database'}]
data_string = json.dumps(success_msg)
self.response.headers.add_header('content-type', 'application/json', charset='utf-8')
self.response.write(data_string)
When I get the response it is skipping the success function and going directly to the error.
Logging the error values im not getting any thing meaningful:
the error is:
The text status is:error
The jqXHR is:[object Object]
Chrome's console is giving me the error:
Resource interpreted as Document but transferred with MIME type application/json:
I looked that up and the solutions on SO did not work, I think this is an error with the server side code:
self.response.headers.add_header('content-type', 'application/json', charset='utf-8')
If I comment out the above line I get no error in chrome and I just get back the response on a blank page with the correct values in the following format:
[{"msg": "Successfully saved to the database", "class": "success"}]
In the above case it does save to the database so I cannot seem to find anything wrong except for the header and simply don't know how to proceed!
EDIT
The error it seems is from the server side I had removed the following line:
event.preventDefault();
from my script and it caused all the problems now at least Im getting a clear indication of where the problem is. It's from incorrectly getting the posted data, how would I do it the correct way? I tried the following:
json_data = self.request.GET.items()
decoded = json.loads(json_data)
but Im getting a TypeError: expected string or buffer on the following line:
json_data = self.request.GET.items()
Have a look in your debugger. You receive a JSON string in your post (webapp2 multidict). You have to decode this string using json.loads, resulting in a python object.
Here is my jquery code to send and receive json :
function gaeQuery(request) {
var url = "/query";
var payload = {'jsondata' : JSON.stringify(request)};
$.post(
url,
payload,
function(response) {
procesResponse(response);
}, // succes response callback
'json', // response contains JSON content, and will be decoded in a js object
{
contentType: "application/json;charset=utf-8", // send JSON content
timeout: 20000,
tryCount: 0,
retryLimit: 3, // max 3 retries
error: function(xhr, textStatus, errorThrown) { // error handling callback
if (textStatus === 'timeout') {
this.tryCount++;
if (this.tryCount <= this.retryLimit) { //try again until retryLimit
$.ajax(this);
return;
}
alert('We have tried ' + this.retryLimit + ' times and it is still not working. We give in. Sorry.');
return;
}
if (xhr.status === 500) { // internal server error
alert('Oops! There seems to be a server problem, please try again later.');
}
else {
alert('Oops! There was a problem, sorry.'); // something went wrong
}
}
}
);
}
OK so I managed to figure this out and thought I will post the answer that worked for me to help anyone looking for this information because the webapp2 docs are not that helpful when it comes to 'getting' posted json data.
on the client side I did the following:
var request = $.ajax({
url: "/some/url/",
type: "POST",
data: JSON.stringify([{someval: val1, someval2:val2, someval3:val3}]),
contentType: "application/json",
dataType: 'json',
beforeSend: function() {
$('#loading-div').show();
},
complete: function(){
$('#loading-div').hide();
},
success: function(response, textStatus, jqXHR){}
});
The reason I couldnt figure out the problem straight away was because of the following line which I deleted along with some commented out line which prevented the page from redirecting after posting. This was the source of all the weird, unrelated and unhelpful error messages:
event.preventDefault();
on the server side to get the json data being posted to appengine do the following:
jdata = json.loads(cgi.escape(self.request.body))
for vals in jdata:
val1 = vals['someval']
val2 = vals['someval2']
val3 = vals['someval3']
The above was the root of the problem I wasn't doing it right and without the previous line on the client side there was no way to figure it out.
Anyways once you have the data do whatever processing you need to do with it and once you are done and need to send back a json response add the following lines:
//the data would look something like this
data = {'return_value': val1, 'return_value2': val2,
'return_value3': val3, 'return_value4': val4}
return_data = json.dumps(data)
self.response.headers.add_header('content-type', 'application/json', charset='utf-8')
self.response.write(return_data)
Almost forgot on the client side again to access the variables sent back from the server with jquery its very straight forward...do something like:
success: function(response, textStatus, jqXHR){
console.log(response.return_value);
console.log(response.return_value2);
console.log(response.return_value3);
}
Hope this will help someone seeking this information.

Is it OK to pass both token and client_id to the client when Channel API is used?

I need to create an application, where GAE server will always talk with just one client (i.e. one message should be always sent just to one client).
I do the following -
Python:
def get(self):
# generate token, when page is loaded
client_id = uuid.uuid4().hex
token = channel.create_channel(client_id)
template_values = {'token': token,
'client_id': client_id
}
self.response.out.write(template.render('page.html', template_values))
def post(self):
# reply to the client
...
client_id = self.request.get('id')
channel.send_message(client_id, message)
Javascript:
sendMessage = function(field) {
$.ajax({
type: "POST",
url: "/",
data: "f=" + field + "&id=" + "{{ client_id }}", // WARNING!
contentType: "application/x-www-form-urlencoded",
success: function(data) {
}
});
};
onOpened = function() {
connected = true;
sendMessage('opened');
};
onMessage = function(msg) {
alert(msg.data);
};
onError = function(err) {
alert(err);
};
onClose = function() {
alert("close");
};
// open new session
channel = new goog.appengine.Channel('{{ token }}'); // WARNING!
socket = channel.open();
socket.onopen = onOpened;
socket.onmessage = onMessage;
socket.onerror = onError;
socket.onclose = onClose;
It works well, but with such scenario both token and client_id are passed to the client. Is it OK?
There's no technical reason not to do this. If you're worried about security, the token is far more valuable: an attacker who could listen to your traffic could take the token and listen to channel messages in a different context. The clientid wouldn't let them do that.
But I do have a question: why not return the message in the POST response, rather than sending a message over the channel? Or is the sample code just simplified for the example?

Categories