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
Related
I'm trying to make a webpage in which you can specify a number of vectors, then insert modulus and angle for each one, and it will calculate the sum.
My code can do the calculation, but I can't properly display the result on my template.
views.py:
def sum_view(request):
if request.method == "POST":
message = ''
for j in range(2,12):
if not request.POST.get(f'vector_mod_{j}'):
num_vett = j - 1
result = Vector(0, 0)
for i in range(num_vett):
mod = float(request.POST.get(f'vector_mod_{i+1}'))
ang = float(request.POST.get(f'vector_ang_{i+1}'))
result += Vector(mod, ang)
message = f'Modulus: {result.modulus}, angle: {result.angle}°'
return JsonResponse({'message': message})
return render(request, 'vectsum/sum.html')
The problem is that when I submit I see a sort of firefox developer tools view with a menu including 'JSON', 'Raw Data', 'Headers', and the correct message displayed in a console-like way.
Here is the ajax part of my template:
$(document).on('submit','#calculate',function(e){
e.preventDefault();
$.ajax({
type:'POST',
headers: {'X-Requested-With': 'XMLHttpRequest'},
url:'/vectorialsum/',
data: $('#calculate').serialize()
success:function(data){
var mess = JSON.parse(data)['message']
document.getElementById('result').innerHTML += mess
}
})
});
Probably I don't get what return JsonResponse does, however how do I show the message in my page?
Edit:
maybe my question is not clear, I'll rephrase: how can I send back to ajax's success function the message variable?
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)
All tutorias of how to use ajax with django said I should do something like this. But is that safe to do this? Cannot someone just change the values in the browser to some malicious SQL? If so, how to prevent it?
javascript
text = this.previousElementSibling.value;
parent = this.parentNode.id;
ajax.open('POST', '/post/comment/', true);
ajax.onreadystatechange = function(){
if(this.readyState == 4) {
reply = document.createElement("DIV");
reply.classList.add('post');
reply.innerHTML = this.responseText;
document.getElementById('comments').appendChild(reply);
}
}
ajax.setRequestHeader("X-CSRFToken", csrf_token);
ajax.setRequestHeader('Content-Type', 'application/json');
ajax.send(JSON.stringify({'text': text,'parent': parent}));
views.py
def post_comment(request):
if request.method == 'POST':
body = json.loads(request.body.decode('utf-8'))
parent = Post.objects.get(pk=body['parent'])
comment = Comment.objects.create(
author=request.user,
parent=parent,
group=parent.group,
text=body['text']
)
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
});
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 })