Django - Ajax POST JS variables to initialize form - javascript

I am working on a django project in which I have gathered up all of my variables in js and am trying to initialize a form (inside a modal popup) on same page without any refresh. I have the form showing up inside my modal, but can't quite figure out the Ajax post method to get my js variables into the initial form fields. Any help would be much appreciated!
index.html - this function fires where I need it, but returns the page url instead of the data object I am trying to define.
Index.html
$.ajax({
method: "POST",
url: '',
data: {
geology: ('#geology').value,
latitude: ('latitude').value,
longitude: ('longitude').value,
csrfmiddlewaretoken: '{{ csrf_token }}',
},
success: function(data){
console.log(data.geology);
},
error: function(error_data){
console.log("error");
console.log(error_data);
}
});
views.py
def home_view(request):
geology = request.GET.get('geology')
latitude = request.GET.get('latitude')
longitude = request.GET.get('longitude')
form = MineralForm(initial={'mineral': mineral, 'geology': geology, 'latitude': latitude, 'longitude': "INITIAL", 'description': description}) # populates form with what user tried to submit...
UPDATE:
Here is an update on where I am at:
The modal window opens after an api call to gather some geology data. I am hoping to populate this form with the geology data, without refreshing the page. I am using ajax to create a post that get's my data object over to views.py (I am able to print the data upon POST from views.py into the terminal) but the form is not initializing with the data. Instead, it is initializing with the "PRE_POST" values, even after the api call to gather the data and post via ajax.
Any thoughts on what might be going on here, or how to resolve would be much appreciated!
matMap.html (snippets)
<!-- mineralForm Modal -->
<div class="modal fade draggable" id="mineralFormModal" role="dialog" style="height: 100%;">
<!-- Modal content-->
<div class="modal-header">
<button id ="mineralFormModalClose" type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title" align="center" style="font-family: Lobster">Add New Mineral</h4>
</div>
<div class="mineralFormModal_body" id="mineralFormModal_body" style="position:absolute; top:0">
<h3>loading before modal clears</h3>
</div>
<br>
{{ form }}
<br>
<button id="modalSave" type="button" class="btn btn-default" data-dismiss="modal">Save</button>
<div class="modal-footer red lighten-3">
<button id="modalClose" type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
(...)
$.ajax({
method: "POST",
url: '',
data: {
geology: geology,
latitude: x,
longitude: y,
csrfmiddlewaretoken: '{{ csrf_token }}',
},
success: function(data){
console.log("AJAX POST SUCCESS!"); //grabs this entire page and all variables.
},
error: function(error_data){
console.log("error");
console.log(error_data);
}
});
views.py
def home_view(request):
geology = request.POST.get('geology')
latitude = request.POST.get('latitude')
longitude = request.POST.get('longitude')
if request.method == "POST":
print("!!!! POSTING from HOME !!!!" + geology + " " + latitude + " " + longitude)
form = MineralForm(request.POST, initial={'geology': "POST_VALUE",'latitude': "POST_VALUE", 'longitude': "POST_VALUE"})
print("NOW WE ARE POSTING: ")
print(form)
return render(request, 'blog/matMap.html', {'form': form})
else:
print("LOADING HOME: INITIAL STATE (BEFORE POST)")
form = MineralForm(initial={'geology': "PRE_POST",'latitude': 'PRE_POST', 'longitude': 'PRE_POST'}) # populates form with what user tried to submit...
return render(request, 'blog/matMap.html', {'form': form})
And here is my terminal output, from initial page load through after the ajax post:
LOADING HOME: INITIAL STATE (BEFORE POST)
[13/Feb/2019 13:36:07] "GET / HTTP/1.1" 200 41261
Not Found: /js/scripts.js
[13/Feb/2019 13:36:07] "GET /js/scripts.js HTTP/1.1" 404 3210
Not Found: /js/scripts.js
[13/Feb/2019 13:36:08] "GET /js/scripts.js HTTP/1.1" 404 3210
[13/Feb/2019 13:36:08] "GET /api/chart/data/ HTTP/1.1" 200 4039
!!!! POSTING from HOME !!!!Miocene -119.48709 44.85346
NOW WE ARE POSTING:
<tr><th><label for="id_mineral">Mineral:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="mineral" required id="id_mineral"></td></tr>
<tr><th><label for="id_description">Description:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><textarea name="description" cols="40" rows="10" required id="id_description">
</textarea></td></tr>
<tr><th><label for="id_geology">Geology:</label></th><td><input type="text" name="geology" value="Miocene" required id="id_geology"></td></tr>
<tr><th><label for="id_latitude">Latitude:</label></th><td><input type="text" name="latitude" value="-119.48709" required id="id_latitude"></td></tr>
<tr><th><label for="id_longitude">Longitude:</label></th><td><input type="text" name="longitude" value="44.85346" required id="id_longitude"></td></tr>
[13/Feb/2019 13:36:30] "POST / HTTP/1.1" 200 41593
However, even after this, when I call up my modal form, it looks like this:
THANK YOU!!!

You're sending data via POST, so initialize your form with it:
form = MineralForm(request.POST or None)

You can not access your POST body data by request.GET use request.POST. And check this doc
def home_view(request):
geology = request.POST.get('geology')
latitude = request.POST.get('latitude')
longitude = request.POST.get('longitude')
form = MineralForm(initial={'mineral': mineral, 'geology': geology, 'latitude': latitude, 'longitude': "INITIAL", 'description': description}) # populates form with what user tried to submit...

Related

jquery load() is not loading my django view in another view

So i have got my html and i would like to add my django view in div "radio2".
I am using JQuery function Load() but i have a problem because it returns error 404 with get request "http://127.0.0.1:8000/post/afafa/%7B%" and its not loading nothing in div
post_detail.html
<div class="post__recommendation__posts">
<div id="radio2" class="radio2">
</div>
{% for post in posts|slice:":3" %}
<div class="post__recommendation__post">
<div class="post__recommendation__post-image">
<img src={% static post.image.url %} alt="shakhur" />
</div>
<div class="post__recommendation__post-description">{{post.short_description}}</div>
</div>
{% endfor %}
</div>
Js function
$(document).ready(function (){
console.log("Loading page")
$(".radio-btn").click(function(){
console.log("radio - btn")
console.log($(this)[0].id)
$.ajax({
url: "/radio/",
type: 'POST',
data:{
radio: "radio",
input: $(this)[0].id
},
success: update_item()
})
})
})
function update_item() {
$('#radio2').load(
"{% url 'radio2' %}"
);
}
View
#csrf_exempt
def radio_test(request):
return render(request, 'blogapp/radio2.html')
radio2.html
<div class="radiodiv">
This is Radio2
</div>
my results in console
Not Found: /post/afafa/{%
[28/Sep/2020 15:52:19] "GET /post/afafa/%7B% HTTP/1.1" 404 3938
[28/Sep/2020 15:52:19] "POST /radio/ HTTP/1.1" 200 79
[28/Sep/2020 15:52:22] "GET /post/afafa/ HTTP/1.1" 200 10761
It seems that you're trying to use Django's templating engine in a static file.
This will not work because static files are not passed into the templating engine.
There are work-arounds. Easiest is to create a global variable in the main template and pass that into load:
<script>
var radio2_url = "{% url 'radio2' %}";
</script>
Put this before your other script.
Then in your js:
function update_item() {
$('#radio2').load(radio2_url);
}

The record is not saved in the DJango-SQLite database

I am trying to save a record in the database of a model (Score) that is related to two other models (User and Exercise), I receive the form correctly or so I think, and using the save() instruction does nothing. I don't even get errors.
Here the code:
forms.py
class ScoreForm(forms.ModelForm):
#idUser = forms.IntegerField(widget=forms.HiddenInput(), label='idUser')
idExercise = forms.IntegerField(widget=forms.HiddenInput(), label='idExercise')
value = forms.FloatField(widget=forms.HiddenInput(), label='Value')
class Meta:
model = Score
fields = ['idExercise', 'value']
views.py
def save_exercise(request):
if request.method == 'POST' and request.is_ajax:
form_score = ScoreForm(request.POST, instance=request.user)
if form_score.is_valid():
form_score.save()
else:
print('Tenemos un error')
return HttpResponse('Respuesta')
JavaScript
document.getElementById('id_value').value = score;
document.getElementById('id_idExercise').value = idexer
// document.getElementById('id_idUser').value = iduser
let data = new FormData($('#scores').get(0));
Swal.fire({
title: '<strong>Tu resultado: </strong>',
icon: 'success',
html:
`<div class="progress" style="height: 30px;"><div class="progress-bar progress-bar-striped progress-bar-animated" style="width:${number}%">${number}%</div></div>` +
`Ganaste: ${score.toFixed(2)}`,
focusConfirm: false,
confirmButtonText:
'<i class="fa fa-thumbs-up"></i> Okey!',
preConfirm: () => {
$.ajax({
type: "POST",
url: "/polls/save/",
data: data,
processData: false,
contentType: false,
success: function(){
console.log('Funciona!')
show_exercise()
}
})
}
})
In html file
<div class="row d-flex justify-content-center">
<form method="POST" action="" novalidate id='scores'>
{% csrf_token %}
{{ form|crispy}}
</form>
</div>
All the inputs of the form are type hidden since after a couple of calculations I assign their respective values, the form is sent from a modal using AJAX
I can't find an answer, since I don't know what error to look for, could you please help me
The solution was the following, in the file views.py
def save_exercise(request):
scr = Score.objects.filter(idExercise=request.POST['idExercise'], idUser=request.user)
# print(serializers.serialize('json', scr))
exer = Exercise.objects.get(id=request.POST['idExercise'])
if request.method == 'POST' and request.is_ajax():
if scr:
scr.update(value=request.POST['value'])
else:
scr = Score(idUser=request.user, idExercise=exer, value=request.POST['value'])
scr.save()
return HttpResponse('Respuesta')
I was not taking into account the instances related to my Score model.

Check django form validity and javascript

I'm using a django model form and I want to protect me from malicious user input (not just wrong input).
From my understanding django forms are enough secure: .is_valid() check user input, csfr protect from cross site forgery.
But this time my form isn't using action='/path/to/my/view' to call a django view, instead my submit button calls a javascript function and this function takes the data and calls a django view using ajax to access the database and then shows the results on screen.
So I don't think to be protected anymore (.is_valid() is not called, csfr is not sent). I'm right? and if so what I should do?
I think:
1) This is not a problem, the form is reasonable secure (why?)
2) Refactor the code and using a django view
3) Neither the django form validation is enough secure so anyway I should do something more (what?)
4) My javascript function is sending the data to a django view using ajax. I should use that data to instantializate a bound form and use .is_valid() on that, but anyway I'm not using csfr, right?
5) Using html validators (to me they don't look adapt to check against malicious input data)
6) Other?
Some code, to be complete but probabily you wont need it
my forms.py:
class NameListForm(forms.ModelForm):
class Meta:
model = Name
fields = ['namelanguage', 'nametype', 'gender']
widgets = {
'gender': forms.CheckboxSelectMultiple(),
}
My models.py:
class Name(models.Model):
name = models.CharField(_('nome'), max_length=50, default='')
namelanguage = models.ForeignKey(
NameLanguage, related_name='%(app_label)s_%(class)s_language',
verbose_name=_('linguaggio'), on_delete=models.PROTECT)
nametype = models.ForeignKey(
NameType, related_name='%(app_label)s_%(class)s_tipo',
verbose_name=_('tipo'), on_delete=models.PROTECT)
gender = models.ForeignKey(
Gender, related_name='%(app_label)s_%(class)s_gender',
verbose_name=_('sesso'), on_delete=models.PROTECT,
blank=True, null=True)
my template.html:
<form action="" method="post">
<div>
<div class="col-md-auto">
{{ name_list_form.namelanguage.label_tag }}<br />
{{ name_list_form.namelanguage }}
{{ name_list_form.namelanguage.errors }}
</div>
<div class="col-md-auto">
{{ name_list_form.nametype.label_tag }}<br />
{{ name_list_form.nametype }}
{{ name_list_form.nametype.errors }}
</div>
<div class="col-md-auto">
{{ name_list_form.gender.label_tag }}<br />
{{ name_list_form.gender }}<br />
{{ name_list_form.gender.errors }}
</div>
</div>
{{ name_list_form.non_field_errors }}
<div>
<button class="btn btn-primary" id='list_name' type="button" onclick="FilterBy()">{% trans "List Names" %}</button>
<button class="btn btn-primary" type="button" onclick="RandomNames()">{% trans "Random Names" %}</button>
</div>
{% csrf_token %}
</form>
My javascript.js:
function FilterBy() {
var language_id = document.getElementById("id_namelanguage").value;
var nametype_id = document.getElementById("id_nametype").value;
...
$.ajax({type: 'POST',
url: '/lists/get-list-name/',
data: {
language: language_id,
nametype: nametype_id,
...
},
success: function (lista) {
if (lista.result === 'OK') {
//do something
};
}
});
};
My views.py:
def GetListName(request):
if request.is_ajax():
language = request.POST.get('language')
nametype = request.POST.get('nametype')
# it makes sense to check validity here? and anyway I'm not using csfr, right?
# name_list_form = NameListForm({'namelanguage': language, 'nametype': nametype, etc})
# if name_list_form.is_valid():
...
return JsonResponse({'result': 'OK', 'data': my_dict})
CSRF and data validity are two different subject.
First, you can check for CSRF errors by sending the CSRF token in a request header check this.
Second, you can send your data the same way in JS than in a classic form.
// JS, don't forget to add your CSRF headers
$.ajax({
method: "post",
url: "...",
data: {
namelanguage: "foo",
nametype: "bar",
gender: "baz",
});
And just process your form as you do. You can throw an exception if you wan't to be sure you form was submitted from the JS script, but this won't assure you that it really does. Anybody can modify the client headers to make you think so.
# python
from django.http.response import HttpResponseBadRequest, HttpResponseNotAllowed
def GetListName(request):
if not request.is_ajax():
return HttpResponseNotAllowed()
form = NameListForm(data=request.POST)
if not form.is_valid():
return HttpResponseBadRequest()
# do stuff with your form
return JsonResponse({'result': 'OK', 'data': 'some data'})

Passing JSON data from views to html via ajax in Django

I cannot render html template with JSON data passed from views via ajax. I get correct JSON format from views and I can see the correct response in console.log(response), but when I run from the browser this url http://127.0.0.1:8000/our-stores/ I get this result:
[{'fields': {'address': 'Kilpolantie 16',
'city': 'Helsinki',
'country': 'Finland',
'name': 'K-market'},
'model': 'shoppire.supermarket',
'pk': 1},
{'fields': {'address': 'Kontulankari 16',
'city': 'Helsinki',
'country': 'Finland',
'name': 'S-market'},
'model': 'shoppire.supermarket',
'pk': 2}]
But instead of this output I should get rendered ourstores.html file. Please, find the code below:
models.py
class Supermarket(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
country = models.CharField(max_length=50)
def __unicode__(self):
return self.name
urls.py
urlpatterns = [
url(r'^our-stores/$','shoppire.views.ourstores',name='ourstores'),
url(r'^admin/', include(admin.site.urls)),
]
views.py
def ourstores(request):
stores_list = Supermarket.objects.all()
response_data = serializers.serialize('json',stores_list)
return HttpResponse(response_data,content_type="application/json")
ourstores.html
{% extends 'base.html' %}
{% block content %}
<div class='col-sm-12' style='text-align:center'>
<h2>Check out our stores:</h2>
<div id="show_stores" onload="ShowStores()"></div>
<div id="results"></div>
</div>
{% endblock %}
ShowStores.js
$(document).ready(function(){
ShowStores();
});
function ShowStores() {
console.log("show stores is working");
$.ajax({
url : "our-stores",
type : "GET",
dataType : "json",
success: function(response){
$.each(response,function(index){
$('#results').append(response[index].fields.name);
console.log(response[index].fields.name);
});
console.log(response);
console.log("success");
},
error : function(xhr,errmsg,err) {
$('#show_stores').html("<div class='alert-box alert radius' data-alert>Oops! We have encountered an error: "+errmsg+
" <a href='#' class='close'>×</a></div>"); // add the error to the dom
console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
}
});
};
Thanks a lot!
You do not render the ourstores.html template anywhere in your ourstores view. In order for a template to be displayed, it has to be rendered by the view. In your case, if the request is AJAX, you'd want a JSON to be rendered and if the request is not AJAX, the actual template to be rendered.
Your view could look something like this:
def ourstores(request):
if request.is_ajax():
stores_list = Supermarket.objects.all()
response_data = serializers.serialize('json',stores_list)
return HttpResponse(response_data,content_type="application/json")
return render(request, 'ourstores.html')
If you ask for JSON response, JSON response is what you will get.
If you want to render a template, use the following:
def ourstores(request):
stores_list = Supermarket.objects.all()
response_data = serializers.serialize('json',stores_list)
return render_to_response('our_stores.html',
response_data,
context_instance=RequestContext(request))
Then, inside your template use the passed data as {{response_data}}

Django ModelForm and AJAX usage

i am working on for a basic feedback system. I just want to submit feedback with ajax, for example if fields are empty ajax will return some error msg and update the div at the same page with no redirection. if everything is ok it will update the feedbacks div with the new one...
Here is my code
models.py
from django.db import models
# Create your models here.
class FeedBack(models.Model):
title = models.CharField(max_length=255)
description = models.TextField()
def __unicode__(self):
return self.title
class Meta:
ordering = ["-title"]
views.py
import json
from django.shortcuts import *
from django.template import RequestContext
from submission.forms import *
def feedback(request):
if request.method == "POST":
form = FeedBackForm(request.POST)
message = 'Oops!'
if(form.is_valid()):
message = request.POST['title']
return HttpResponse(json.dumps({'message': message}))
return render_to_response('index.html',
{'form':FeedBackForm()}, RequestContext(request))
urls.py
from django.conf.urls import patterns, include, url
from submission.views import *
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^feedback/', feedback, name='feed_back'),
)
index.html
<html>
<head>
<script type="text/javascript" src="../static/helper.js"></script>
</head>
<body>
<h1>Leave a Suggestion Here</h1>
<div class="message"></div>
<div>
<form id="feed_form" action="" method="POST">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit Feedback" />
</form>
</div>
</body>
</html>
helper.js
$(document).ready(function() {
$('#feed_form').submit(function() { // catch the form's submit event
$.ajax({ // create an AJAX call...
data: $(this).serialize(), // get the form data
type: $(this).attr('method'), // GET or POST
url: '', // the file to call
success: function(data) { // on success..
$('.message').html(data); // update the DIV
},
error: function(e, x, r) { // on error..
$('.message').html(e); // update the DIV
}
});
return false;
});
});

Categories