request through ajax render to a page not working django - python

After making an ajax request data is being sent successfully to view. But the render function is not working. Render function should render to dashboard.html with data. I have imported all files needed to render. Is it because of an ajax request. Thanks in advance...
My ajax request from template
$("#campaign").click(function () {
alert("hey main")
alert($("#campaign").val());
var id = $("#campaign").val()
$.ajax({
type: "POST",
url: "{% url 'appdata' %}",
data: {
userid: id
}
}).done(function () {
alert("Data Sent: ");
}).fail(function () {
alert("error");
});
/* location.reload()*/
});
My urls.py
url(r'^publisher/appdata/?$', 'appdata', name='appdata'),
My views.py
def appdata(request):
print 'hi i am appdata, fetch me after select id'
print request
userid = request.POST['userid']
# print 'userid: %s'%userid
impressions = Impressions.objects.get(id=userid)
# print 'impressionid: %s'%impressions.id
clicks = Clicks.objects.get(id=userid)
revenues = Revenue.objects.get(id=userid)
ecpm = App.objects.get(id=userid)
member = Member.objects.get(id=userid)
campaigns_id = Campaign.objects.get(id=userid)
# print campaigns_id
# print type(campaigns_id)
apps = App.objects.all()
# print apps
# for i in apps:
# print i.name
# print len(camps)
# dict = {'i':impressions, 'c':clicks, 'r':revenues, 'e':ecpm, 'apps': apps, 'member':member, 'c_id':campaigns_id }
# print dict['i'].impressions
return render(request, 'dashboard.html', {'i':impressions, 'c':clicks, 'r':revenues, 'e':ecpm, 'apps': apps, 'member':member, 'c_id':campaigns_id })

Related

Django multiple AJAX queries for images

I made a button the user can click and it makes a AJAX GET request to the backend class Image. The response is the image url. I paste the url into a image tag and display it on the template
models.py
class Image(models.Model):
img = models.ImageField()
views.py
def ajax(request):
from django.http import JsonResponse
if request.is_ajax():
image = request.FILES.get('data')
aaa = Image.objects.get(id=1)
aaa = str(aaa.img.url)
return JsonResponse({'image_query': aaa}, status=200)
return render(request, 'components/ajax.html')
AJAX (template)
<button id="getData" class="btn btn-success">Get</button>
<div id="seconds"></div>
...
<script>
$(document).ready(function () {
$('#getData').click(function () {
$.ajax({
url: 'ajax',
type: 'get',
data: {
data: $(this).text()
},
success: function (response) {
$('#seconds').append('<img src="' + response.image_query + '" width="300">')
}
})
})
})
</script>
Everything works fine and the image is rendered to the template! Now I dont want to query the image with ID=1, I want all images to be fetched to the template.
I tried to do by adding a for loop into the views.py but it only returns the first element.
if request.is_ajax():
image = request.FILES.get('data')
for i in range(1, 5):
aaa = Image.objects.get(id=i)
aaa = str(aaa.img.url)
return JsonResponse({'image_query': aaa}, status=200)
I don't know what to modify that it will query every image in the DB. Does someone have a solution for my problem?
It's returning the only first element because you are returning inside the for loop, instead put the return 1 indent back, and put all of the urls in array.
... # code you have above
images = []
for i in range(1, 5):
aaa = Image.objects.get(id=i)
images.append(aaa.img.url)) # append the url to the list
return JsonResponse({'images': images}, status=200) # 1 indent back
as a result you'll have to change your javascript code like this.
const success = (response) => {
// Loop through each of the links
for (let i=0; i < response.image_query.length; i++) {
$('#seconds').append('<img src="' + response.image_query[i] + '" width="300">')
}
}
// ... Other code
$.ajax({
url: 'ajax',
type: 'get',
data: {
data: $(this).text()
},
success: success,
});
Also be carefull with $('#seconds').append('<img src="' + response.image_query + '" width="300">'), appending raw html could cause an XSS attack, if you are not completely sure that response.image_query is safe do not do this. (Since it is a url it should be escaped)

error to save history chess into db sqlite django

I use django 2.1 and combine its with nodejs.
the game is ok but when game end, I want to save history into db of django. But it's not run. I'm not sure where is issue
static\main.js
winner = checkLogout !== username ? username : checkLogout;
history= game.history();
socket.emit('endgame', {'gameId':gameId,'player1':player1, 'player2':player2, 'winner': winner, 'history': history.toString(), note : checkLogout });
nodejs\index.js
var http = require('http').createServer().listen(4000);
var io = require('socket.io')(http);
var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
var xhttp = new XMLHttpRequest();
var host = 'localhost';
var port = '8000';
io.on('connection', function (socket) {
socket.on('endgame', function(msg){
var url = 'http://' + host +':' + port + '/save_game/';
xhttp.onreadystatechange = function() {
if(this.readyState === 4 && this.status === 200) {
if(xhttp.responseText === "error")
console.log("error saving game");
else if(xhttp.responseText === "success")
console.log("the message was posted successfully");
}
};
xhttp.open('POST', url, true);
xhttp.send(JSON.stringify(msg));
});
});
game\views.py
import json
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from game.models import Game
from django.http import HttpResponse, HttpResponseRedirect
from django.views.decorators.csrf import csrf_exempt
#login_required
def index(request):
return render(request, 'index.html')
#csrf_exempt
def save_game(request):
if request.method == 'POST':
msg_obj = json.loads(request.body.decode('utf-8'))
try:
msg = Game.objects.create(gameId=msg_obj['gameId'], player1=msg_obj['player1'], player2=msg_obj['player2'], winner = msg_obj['winner'], history = msg_obj['history'])
msg.save()
except:
print("error saving game")
return HttpResponse("error")
return HttpResponse("success")
else:
return HttpResponseRedirect('/')
update code static\main.js
socket.on('joingame', function (msg) {
gameId = msg.game.gameId;
player1 = username;
player2 = oppDict;});

How to get only json value using jquery from calling an API?

The API returns both JSON and also render the template and when i call $.getJSON it will only return that render template but not JSON value. I have tried this
if request.args['type'] == 'json':
return json.dumps(group)
else:
return render_template("/c.., summary=json.dumps(group))
but it says
bad request
Is there any way I can get that JSON value whenever I need it?
This is my view
#cms.route('/add/asset/<client_id>', methods=["GET"])
#login_required
def asset_add(client_id):
if int(current_user.id_) == int(client_id):
group = {}
group['id'] = []
group['pid'] = []
group['name'] = []
for index in range(len([r.id_ for r in db.session.query(Assetgroup.id_)])):
for asset in (Assetgroup.query.filter_by(parent_id=(index or ''))):
group['id'].append(asset.id_)
group['pid'].append(asset.parent_id)
group['name'].append(asset.name)
if request.args['type'] == 'json':
return json.dumps(group)
else:
return render_template("/cms/asset_add.html", action="/add/asset", asset=None,
client_id=client_id,
types=Type.query.all())
else:
return 'permission denied'
and this is my ajax request
$(document).ready(function () {
$('#group_id').click(function () {
$.getJSON(
'/add/asset/' + {{ client_id }},
function (data) {
$('#group_id').find('option').remove();
var len = data.id.length;
for (var i = 0; i < len; i++) {
var option_item = '<option value="' + data.id[i] + '">' + data.name[i] + "</option>";
$('#group_id').append(option_item);
}
}
);
});
});
You can add parameter in html call to get the json result...
i.e)
const Endpoint = '/add/asset/?'
$.getJSON(Endpoint, {type: 'json'}).done(function(data...)
I believe this is what you are looking for
http://flask.pocoo.org/docs/0.12/api/#flask.Request.is_json
That is a flask method that checks if the request is json
Then you can use jsonify still in flask to return json (you need to import it though)
from flask import jsonify
so your code becomes
if request.is_json:
return jsonify(group)
Hope you find that useful and more elegant
One of the easier ways to debug is just return json alone for a start to see how the response looks in a browser. So you can remove login required (assuming you are not yet in production), do not check if the request is_json, then call the api and see what it returns. So assuming your client id is 1
#cms.route('/add/asset/<client_id>', methods=["GET"])
def asset_add(client_id):
if int(current_user.id_) == int(client_id):
group = {}
group['id'] = []
group['pid'] = []
group['name'] = []
for index in range(len([r.id_ for r in db.session.query(Assetgroup.id_)])):
for asset in (Assetgroup.query.filter_by(parent_id=(index or ''))):
group['id'].append(asset.id_)
group['pid'].append(asset.parent_id)
group['name'].append(asset.name)
return jsonify(group)
Now you can visit http://yoursite.com/add/asset/1 to see your response

JSON data not reaching view pyramid

I'm trying to build a page where when the user presses a button a variable which initially is 0 increments with 1. This number is then sent asynchronously to the server by using jQuery AJAX.
What I have so far is:
In my __init__.py file:
def main(global_config, **settings):
engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind = engine)
Base.metadata.bind = engine
config = Configurator(settings = settings)
config.include('pyramid_jinja2')
config.add_static_view('static', 'static')
config.add_static_view('scripts', 'scripts')
# Removed the other views
config.add_route("declare_usage", '/user/{user_id}/{address_id}/declare')
config.add_route("declare_usage_json",'/user/{user_id}/{address_id}/declare.json')
config.scan()
My HTML + Jinja2:
#Removed code for simplicity
<div id="button_add">Add</div>
{{val}}
My JS:
$(document).ready(function(){
var room = 0;
jQuery.ajax({type:'POST',
url: '/user/1/5/declare', #I use a direct user ID and a direct address ID as I'm not sure how to send this to JS from Pyramid ... yet :).
data: JSON.stringify(room),
contentType: 'application/json; charset=utf-8'});
$('#button_add').click(function(){
room = room + 1;
});
});
My view code:
#view_config(route_name = 'declare_usage', renderer = 'declara.jinja2')
#view_config(route_name = 'declare_usage_json', renderer = 'json')
def declara_consum(request):
#Removed code for simplicity
val = request.POST.get('room') #I get a "None value in my html" if I change to request.json_body -> I get an error that there is no json to be parsed.
return { 'val' : val }
What happens is that when I open the debugger the POST request is successful with no data and on the page I get 2 options for 'val':
None -> When I use val = request.POST.get('room')
Error ValueError: No JSON object could be decoded -> When I use val = request.json_body
Also, still can't get it to work if in my JS i change url to be /user/1/5/declare.json and/or data to {'room' : room}
Can somebody please point out what I'm doing wrong?
you don't need another route declare_usage_json, just need separate two function like this
#view_config(route_name = 'declare_usage', renderer = 'declara.jinja2')
def declara_consum(request):
# this will response to your jinja2
return { 'val' : val }
#view_config(route_name = 'declare_usage', xhr=True, renderer = 'json')
def declara_consum_ajax(request):
# this will response to your asynchronously request
val = request.POST.get('room')
return { 'val' : val }
when you send a request using ajax, this will goto the second function.
$.ajax({
type: 'POST',
url: '/user/1/5/declare',
data: {'room' : room},
dataType: 'json'
}).done(function(response){
// update your data at html
});

Pass arguments to multiple forms with the same request in Django

I am new in django and I have a doubt:
Is possible pass arguments to a several forms.
Scenario:
I have an html table rendered with django-tables2, in the first column I have a drop down button. One item from the drop down button open a bootstrap modal window with 3 diffetent forms(all the forma re modelbased forms).
The arguments are pased with a javascript function, the function take the value from some cells of the html table and send this value as argument.
All this form take the same arguments. I can pass the arguments to one form but I need to pass the arguments to all the forms.
In simple words:
How can I pass arguments to various forms in the same post request?
How I say above I am new with django and I don't know if is possible get this functionality.
UPDATE
my forms: (all the forms have the same code. nonly the name change)
class RecepcionForm(forms.ModelForm):
def __init__(self,*args,**kwargs):
super(RecepcionForm,self).__init__(*args,**kwargs)
self.helper = FormHelper(self)
self.helper.layout.append(Submit('save','Grabar'))
class Meta:
model = DetalleRecepcion
my views:(all the form use a view like this. only the name of the view change
def RecepcionView(request):
idp = request.GET.get('i')
anio = request.GET.get('a')
mes = request.GET.get('m')
if request.method == 'POST':
r = DetalleRecepcion.objects.get(id_proveedor=idp,anio=anio,mes=mes)
form = RecepcionForm(request.POST, instance=r)
if form.is_valid():
form.save()
return HttpResponseRedirect('/monitor/')
else:
r = DetalleRecepcion.objects.get(id_proveedor=idp,anio=anio,mes=mes)
form = RecepcionForm(instance=r)
return render_to_response('recepcion.html',
{'form':form},
context_instance=RequestContext(request))
I only know how to pass the value to an unique form. I use this fucntion:
<script type="text/javascript">
function param(){
var tbl = document.getElementById("myTable");
var rows = tbl.rows;
var argu = "";
for (var i = 0; i < rows.length; i++){
rows[i].onclick = function(){
idpro = this.cells;
argu = "?i="+idpro[0].innerHTML+"&a="+idpro[1].innerHTML+"&m="+idpro[2].innerHTML;
window.location = "/recepcion/"+argu;
}
}
}
</script>
I know that function is really bad coding, but I have some trouble to redirect toe the template using ajax post request.
I try to use this function but I can never redirect to the form where i send the parameters
<script type="text/javascript">
function param(){
$(function(){
//var http = new XMLHttpRequest();
var tbl = document.getElementById("myTable");
var rows = tbl.rows;
var url = "/recepcion/";
for (var i = 0; i < rows.length; i++){
rows[i].onclick = function(){
idpro = this.cells;
ano = this.cells;
mes1 = this.cells;
$.ajax({
async : false,
type:"GET",
url: "/recepcion/",
datatype: 'json',
data: ({i: idpro[0].innerHTML, a: ano[1].innerHTML, m: mes1[2].innerHTML }),
success: function(){
}
});
}
}
});
return false;
}
</script>
Any idea or advice how can I achieve this functionality.?
Thanks in advance

Categories