Unable to print the variable passed from view to template - django

I am trying to pass the variable ,I am obtaining from view to the template but it is showing in the preview of the web-browser(chrome) but not on actual screen.
Following is my view file:
analyzer=SentimentIntensityAnalyzer()
data={}
with open('today_5th_oct_new.csv','r',newline='', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
data[row[0]]=float(row[1])
analyzer.lexicon.update(data)
def index(request):
return render(request, "gui/index.html")
#csrf_exempt
def output(request):
sentences = request.POST.get('name',None)
senti = analyzer.polarity_scores(sentences)
context_dict = {'sentiment': senti}
return render(request,"gui/index.html", context = context_dict)
Following is my template-
<!doctype html>
<html>
<head><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script></head>
<body>
<form action>
Enter Sentence:<input id = "name" type = "text" name = "EnterSentence" encoding = "utf-8"><br>
<input onclick = "testfunction()" type = "button" value = "Submit" >
</form>
<div><strong>Score is {{ sentiment }}</strong></div>
</body>
<script>
var testfunction = () => {
var test = document.getElementById("name").value
console.log(test)
$.ajax({
type: "POST",
dataType: "json",
url: 'output/',
data:{
csrfmiddlewaretoken: '{{ csrf_token }}',
'name': test
},
success: function(response) {
console.log("Succesful return firm ajax call");
},
error: function(result){
console.log("Failure");
}
});
}
</script>
I am observing the desired output in preview but not on actual page.
How to resolve that ?

You're getting the response via Ajax but you're not doing anything with it. Your success function needs to insert the content into the page somehow.
To be honest, I don't see why you use Ajax here at all; if you removed the JS code and just let your form do a POST directly it would work fine.

Related

Ajax Post Request isn´t working in django

I have a problem with django. I have researched so much on other questions but their answers don´t work for me. I need to send a base64 string of an image to my view so that i can store the string instead of the image in my database. So, I want to send data via ajax to my django view. Due to whatever reason, the form gets already submitted by django automatically and i tried to stop it, but then ajax isn´t firing too. I would really appreciate help because it already has cost me so much time.
add.html
<form method="post" enctype="multipart/form-data" onsubmit="submitdata()">
{% csrf_token %}
<input type="text" name="dish" required id="id_dish" placeholder="Rezeptname">
<img ><input type="file" name="image" required id="id_image" accept="image/*">
<div class="image-upload"><img id="img_id" src="#">
</div><button type="submit">Upload</button>
</form>
<script>
function submitdata() {
$.ajax({
type: "POST",
contentType: "application/json",
url: "/add",
data: JSON.stringify({
csrfmiddlewaretoken: document.getElementsByName("csrftoken")[0].value,
"dish": "test",
"image": dataurl,
"recipe": document.getElementsByName("recipe")[0].value,
"caption": document.getElementsByName("caption")[0].value
}),
dataType: "json",
});
}
</script>
views.py
#login_required(login_url="login")
def add(response):
if response.method == "POST":
form = AddForm(response.POST, response.FILES)
if form.is_valid():
print(response.POST)
# The print statement prints the data from the automatical form
submit, not from the ajax submit
current_user = Client.objects.get(id=response.user.id)
current_user.post_set.create(poster=response.user.username,
dish=form.cleaned_data.get("dish"),
image=response.POST.get("image"),
caption=form.cleaned_data.get("caption"),
recipe=form.cleaned_data.get("recipe"))
messages.success(response, "You successfully added a post.")
return redirect("home")
else:
form = AddForm()
return render(response, "main/add.html", {"form":form})
urls.py
urlpatterns = [
path("add", views.add, name="add")
]
forms.py
class AddForm(forms.ModelForm):
dish = forms.CharField()
image = forms.FileField()
caption = forms.TextInput()
recipe = forms.TextInput()
class Meta:
model = Post
fields = ["dish", "image", "recipe", "caption"]
When you use the onsubmit property and want to prevent the form from sending data, make sure the handler returns false.
If the onsubmit handler returns false, the elements of the form are not submitted. If the handler returns any other value or returns nothing, the form is submitted normally.
<script>
function submitdata() {
$.ajax({
type: "POST",
contentType: "application/json",
url: "/add",
data: JSON.stringify({
"dish": "test",
"image": dataurl,
"recipe": document.getElementsByName("recipe")[0].value,
"caption": document.getElementsByName("caption")[0].value
}),
dataType: "json",
//return false if ajax is successful
// you can also do something with response data if needed
success: function(data) {return false;},
//return false if ajax request returns error
error: function(data) {return false;},
});
}
</script>

getting undefined after ajax get call to fetch from postgres db in django

I am trying to fetch data from postgres table by clicking a button in the django template page and the fetched data from db should be populated into another div.
For the same, I am using Ajax get call to fetch the data from DB, but I am facing problem that the value is shown as undefined.
With the Ajax call if I populate the target div with the below, it is working.
$('#childContainer').html(10 + Math.floor(Math.random()*91));
But when I try to fetch the data from table, I am getting undefined.
Here is the code which I have written:-
views.py:-
def index(request):
distinctenvapp = Env_app.objects.values('environment_name').distinct()
return render(request, 'envconfigmgmt/index.html', {'distinctenvapp' : distinctenvapp});
def get(self,request, *args, **kwargs):
if self.request.is_ajax():
return self.ajax(request)
def ajax(self, request):
response_dict= {
'success': True,
}
action = request.GET.get('action','')
if action == 'get_appnames':
env_id = request.GET.get('id','')
if hasattr(self, action):
response_dict = getattr(self, action)(request)
envappname = Env_app.objects.get(environment_name='env_id')
response_dict = {
'application_name':envappname.application_name
}
return HttpResponse(simplejson.dumps(response_dict),
mimetype='application/json')
index.html:-
<div><center><table id="t1"><tr>
{% for obj in distinctenvapp %}
<td>
<button id="{{ obj.environment_name }}">
{{ obj.environment_name }}
</button>
</td>
{% endfor %}
</tr></table></center></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("button").click(function(){
$env_id = $(this).attr('id')
$.ajax({
type: "GET",
data: { action: "get_appnames", id: $env_id },
success: function(data){
$("#childContainer").html("<strong>"+data.application_name+"</strong>");
console.log(data);
}
});
//$('#childContainer').html(10 + Math.floor(Math.random()*91));
});
});
</script>
<div id="childContainer"></div>
I expect the data to be fetched in the target child div.
It should show application names like App1, App2 etc, but it is showing undefined.
IF your ajax request returning JSON content then you have to define datatype in Ajax parameter
$.ajax({
type: "GET",
data: { action: "get_appnames", id: $env_id },
dataType: 'json',
success: function(data){
$("#childContainer").html("<strong>"+data.application_name+"</strong>");
console.log(data);
}
});
For more refere this https://api.jquery.com/jquery.ajax/
I think your ajax request doesnt have url so ajax called current page again
current page is a string and doesnt have application_name
be aware that the mimetype argument was removed in Django 1.7. Use content_type instead.

Pass a rendered view to another app's view in Django

I'm trying display the outputs of 2 apps on a same web page, but am encountering issues when trying to use the solution proposed here.
I have a "main_app" handling the content of most of the page, and would like to add the output of a "sub_app" (i.e. a rendered <div> element) on the same page.
Here's how I collect the output of sub_app in a main_app view:
from sub_app.views import sub_app_view #
def main_app_view(request):
my_sub_app_html = user_tests(request) #supposed to get rendered HTML content from sub_app
context = {
'sub_app_html ': my_sub_app_html,
}
return render(request, 'main_app.html', context)
Then the view in sub_app:
def sub_app_view(request):
context = {
'sub_app_context': "foo",
}
return render(request, 'sub_app/sub_app.html', context)
main_app.html contains:
<p>
{{ sub_app_html }}
</p>
and sub_app.html:
<div id="mydiv">
{{ sub_app_context }}
</div>
But instead of correctly displaying the rendered HTML from sub_app_view, what is shown in main_app.html in the browser is:
<HttpResponse status_code=200, "text/html; charset=utf-8">.
Is there a solution to this, or a better way to achieve linking between apps?
you can do it using
**
javascript and jquery
**
$.ajax({
type: "get",
url: url_app_1,
data: data,
success: here add your html to your div1,
dataType: dataType
});
$.ajax({
type: "get",
url: url_app_2,
data: data,
success: here add your html to your div2,
dataType: dataType
});
and in the success you can append the html to your div
**
Django solution:
**
The render function return an HttpResponse(content, content_type, status)
so to get the template html you need to:
def main_app_view(request):
my_sub_app_html = user_tests(request)
context = {
# you need to get content then decode
'sub_app_html ': my_sub_app_html.content.decode("utf-8"),
}
return render(request, 'main_app.html', context)
Here is the source code of the render

Passing POST data from form into GET method to generate graph

I'm trying get user input from a HTML form and use that value to populate a ChartJS graph in my Django app called DisplayData which has a template called Display.html. I have an API set up to pass data into ChartJS called display/api/chart/data/ which I use to get two lists to populate the Chart with. In order make the Chart, I am getting data from my models and graphing the data value (integer) against the timestamp of when the value of recorded. This is one of the queries that gets the data:
all_entries = models.Entries.objects.all().filter(parent=2)
Right now, I have it hardcoded to one time of data value (as seen above, to the integer 2), but I would like the user to have a form where they can input a number and submit it, generating the chart by using that integer as a filter. The user input integer would be placed inside the parent= portion of the code above.
I have the following urls set up.
urls.py
urlpatterns=[
url(r'^$',views.DisplayView, name='DisplayView'),
url(r'^api/data/$', views.get_data, name='api-data'),
url(r'^display/api/chart/data/$', views.ChartData.as_view()),
url(r'^logs/', views.LogDisplay, name='Display-Logs'),
]
In order to achieve this, I have added a form in my Display.html file above the code for ChartJs as follows.
Display.html
{% block content %}
<div class="row">
<h4>Enter measurable number:</h4>
<form method="POST">
{% csrf_token %}
<input type="number" name="textfield">
<button type="submit">Submit</button>
</form>
</div>
<div class='padded'>
<div class='col-sm-12' url-endpoint='{% url "api-data" %}'>
<h1>Graph Data</h1>
<canvas id="myChart" width="400" height="400"></canvas>
</div>
</div>
<script>
{% block jquery %}
var endpoint = 'display/api/chart/data/'
var defaultData = []
var defaultLabels = [];
$.ajax({
method: "GET",
url: endpoint,
success: function(data){
defaultLabels = data.labels
defaultData = data.default
console.log(data)
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: defaultLabels,
datasets: [{
label: '# Measurable',
data: defaultData,
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
},
error: function(error_data){
console.log("error")
console.log(error_data)
}
})
{% endblock %}
</script>
{% endblock %}
The first part of the code is the form to get data from the user, the second part is the code to generate the graph which we can ignore right now since the graph works (when I hardcode the value).
In my views file, I have the following code to get the input from the user and then place it in the required place for the query.
views.py
class ChartData(APIView):
authentication_classes = []
permission_classes = []
def post(self, request, format=None):
display_id = self.request.POST.get("textfield")
print(request.data)
try:
display_id = int(display_id)
except ValueError:
display_id = 2
return display_id
def get(self, request, format=None):
display_id = self.request.POST.get("textfield")
print('value of display_id ')
print(display_id)
#insert value from form into parent= below
all_entries = models.Entries.objects.all().filter(parent=display_id)
all_measurables = models.Measurables.objects.all().filter(user_id=request.user.id) #change to current user
all_times = [m.timestamp for m in all_entries]
all_data = []
for m in all_entries:
data = m.data
json_data = json.loads(data)
value = json_data['value']
all_data.append(value)
data = {
"labels": all_times,
"default": all_data,
}
return Response(data)
However, when I run this program, upon entering a number into the textfield and hitting submit the value of display_id seems to be None. Where am I going wrong and how can I achieve what I am trying to do?

Django: How to upload a file using ajax

I am using django 1.5, python 2.7 and jquery 1.9. I have a form which has precisely 2 fields i.e. title and document. When I press submit I want the users chosen document to be present in the request.FILES as shown in the view.
When I submit the regular form (without ajax), this works fine, but with ajax I do not get the file field in my request. Any suggestions on how to upload a file using ajax.
HTML:
<form enctype="multipart/form-data" action="{% url 'upload_document' %}" method="post" id="uploadForm">
{% csrf_token %}
<ul>
<li>
<div>Title</div>
<input id="title" type="text" maxlength="200"/>
<div class="error"></div>
</li>
<li>
<div>Upload File</div>
<input id="document" type="file" size="15" />
<div class="error"></div>
</li>
</ul>
<input type="submit" value="submit"/></p>
</form>
FORMS.PY:
class UploadForm( forms.Form ):
document = forms.FileField()
title = forms.CharField(max_length = 200)
def clean(self):
cleaned_data = super(UploadForm, self).clean()
return cleaned_data
def save(self, *args, **kwargs):
title = self.cleaned_data['title']
doc = self.cleaned_data['document']
document = Document(title = title, document = doc)
document.save()
return document
SCRIPT:
<script type="text/javascript">
$("#uploadForm").submit(function(event){
event.preventDefault();
$.ajax({
url : "{% url 'upload_document' %}",
type: "POST",
data : {csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value,
title: document.getElementById('title').value,
//document: document: document.getElementById('document'),
},
dataType : "json",
success: function( response ){
if(response == "True"){
// success
}
else {
//append errors
}
}
});
});
</script>
VIEWs.PY
def upload_document(request):
print request.POST
print request.FILES
if request.is_ajax():
if request.method == 'POST':
form = UploadForm(request.POST, request.FILES, user = request.user)
if form.is_valid():
form.save()
return HttpResponse(simplejson.dumps('True'), mimetype = 'application/json' )
else:
errors = form.errors
return HttpResponse(simplejson.dumps(errors), mimetype = 'application/json' )
The answer to that question is not that simple. First of all if you intend to support old browsers then indeed it gets nasty. You have to deal with hidden iframes and some JavaScript tricks. I do advice using some well-known scripts for that like jQuery-File-Upload.
But the world is evolving and new technologies arise including HTML5. There's a new File API which is available in most modern browsers ( IE10+, FireFox3.6+, Chrome13+, see: http://caniuse.com/fileapi ) which can be used for that. First you need some HTML:
<input type="file" id="file-select" />
Then you can bind to (for example) change event:
$('#file-select').change( handleFileSelect );
and finally the handler itself:
var data = {};
function createReaderHandler(name) {
return function(ev) {
data[name] = ev.target.result;
};
}
function handleFileSelect(ev) {
var files = ev.target.files; // FileList object
// Loop through the FileList
for (var i = 0; i < files.length; i++) {
var file = files[i],
name = file.name || file.fileName,
reader = new FileReader();
reader.onload = createReaderHandler(name);
reader.readAsText(file);
}
}
Once the data is loaded into JavaScript memory (note that the operation is asynchronous) you can send it via AJAX like any other data. There are more options: depending on your file you can read it as a binary data using .readAsBinaryString and so on. Google is your friend. :)
Also I think there already are good scripts for uploading files with a fallback to old methods. This one can be interesting (haven't tried it):
http://www.plupload.com/
I think the issue is in the submit button, change it into normal button
ie, <button type='button' id='submit'>submit</button>(by default all buttons in form are submit)
and the ajax as
$('#submit').on('click',function(){
frm = $(this).parents('form')
$.ajax({
type: frm.attr('method'),
dataType:'json',
url: frm.attr('action'),
data: frm.serialize(),
async: false,
success: function (data) {
console.log('success')
},
error: function(data) {
console.log("Something went wrong!");
}
})
All others will be same
Just try it will work