What are the options (best way) to update a value of a variable in a template?
template:
<div class="time-container">
{{ time }}
</div>
view:
def index(request):
now = datetime.now()
context = {
'time': now,
}
return render(request, 'times/index.html', context)
I would like to show an actual time (django instance synchronized from ntp) updated every seconds. Should I use a websockets?
Use JavaScript. Here's an example using jQuery and Moment.js:
<!-- this div will contain time -->
<div class="time-container"></div>
...
<!-- include required js libraries -->
<script src="path/to/jquery.js"></script>
<script src="path/to/moment.js"></script>
<!-- now the actual js code to show time -->
<script>
function updateTime(){
$('.time-container').html(moment().format('h:mm:ss'));
};
updateTime();
setInterval(function(){
updateTime();
},1000);
</script>
Related
My question is I need to make a dashboard page. In that, I need to make a chart on day to day created objects by the specific user in Django like the image below.
Also, I need to know how to save data for this like charts.
There are lots of options if you want to create charts. Most of them are JS and/or Ajax which you can include in the template page. Try this Google Charts which I believe is the simplest way to get things up and running,
https://developers.google.com/chart/interactive/docs/gallery/piechart
You can use the parameters from the context dictionary to generate a dynamic graph.
1 From views.py Send the Value of the data (ie the number of Problems solved) through the context Dictionary.
ex: views.py
def index(request):
context = {"problems_solved" : calculated_value}
return render(request, "results.html", context)
in the Template HTML do the following ,
results.html:
{% extends "base.htm" %}
{% load static %}
{% block title %}
results
{% endblock %}
{% block head %}
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
var solved = {{problems_solved}};
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['day', 'problems solved'],
['prob solved', solved ]
]);
var options = {
title: 'Profile progress Report: '
};
var chart = new google.visualization.PieChart(document.getElementById('piechart'));
chart.draw(data, options);
}
</script>
{% endblock %}
{% block body %}
<div id="piechart" style="width: 600px; height: 500px;">
{% endblock %}
If you are looking it to be generated everyday dynamically then you need to append values based with date to the context dictionary and execute the form generation everytime the page gets loaded
I tried to break this problem down into the simplest example. When the request is ajax, rendering the page with an updated context doesn't produce the expected result.
index.html:
<html>
<body>
{% if templateVariable %}
<h1>{{ templateVariable }}</h1>
{% endif %}
<button id="testBtn">TEST</button>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$(function() {
$('#testBtn').click(function(event) {
$.ajax({
type: "POST",
url: "./",
data: {
'x' : 'x',
'csrfmiddlewaretoken' : '{{ csrf_token }}'
}
});
});
});
});
</script>
</body>
</html>
views.py
def index(request):
context = {}
if 'x' in request.POST:
context['templateVariable'] = 'I was updated via ajax'
print('ajax ran')
return render(request, 'index.html', context)
context['templateVariable'] = 'I was not updated via ajax'
print('ajax was not run')
return render(request, 'index.html', context)
When I first load the page, 'ajax was not run' is printed, templateVariable is 'I was not updated via ajax', and the page renders with that in the h1 tag as expected.
When I click the testBtn, I expect the ajax request to trigger the if statement, update the context, and render the page with 'I was updated by ajax' in the h1 tag.
Instead, 'ajax ran' is printed but templateVariable remains 'I was not updated by ajax' when the page is rendered. 'ajax was not run' only is printed once when the page is loaded initially.
Why would I not be getting the expected result?
EDIT: It seems everyone agrees that you cannot return a render and update context variables with an ajax request but I'm still having trouble with this as I believe this is possible. Here's some alternate code:
index2.html:
<html>
<body>
{% if templateVariable %}
<h1>{{ templateVariable }}</h1>
{% endif %}
<h1 id="placeHolder"></h1>
<button id="testBtn">TEST</button>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$(function() {
$('#testBtn').click(function(event) {
$.ajax({
type: "POST",
url: "./",
data: {
'x' : 'x',
'csrfmiddlewaretoken' : '{{ csrf_token }}'
},
success: function (data) {
$('#placeHolder').html(data);
},
dataType: 'html'
});
});
});
});
</script>
</body>
</html>
views2.py
def index2(request):
context = {}
if 'x' in request.POST:
context['templateVariable'] = 'I was updated via ajax'
print('ajax ran')
return render_to_response('notIndex.html', context)
context['templateVariable'] = 'I was not updated via ajax'
print('ajax was not run')
return render(request, 'index.html', context)
notIndex.html:
{% if templateVariable %}
{{ templateVariable }}
{% endif %}
In this example, the page is initially loaded with templateVariable in the context as 'I was not updated via ajax'.
When testBtn is clicked, the ajax request triggers the if block in the view. This renders notIndex.html with the updated context.
The success function of the ajax call sets the generated html from notIndex.html to the h1 tag.
So why is it only possible to trigger a page render with ajax if the page is not the same one that the ajax call came from?
You can't return renders or redirects from AJAX, that's how it works
If you want to update your UI based on something that happens on the server say you have a cart and you'd like to implement 'add to cart' without refreshing the page, the 'add to cart' button must request an endpoint you provided in your urls.py & that url must return true if object is added, or false if it wasn't, but it won't update it on the UI, you need to manually change the cart items count with Javascript.
If you try to redirect or return a render to ajax, it will get the HTML or the redirect/render, nothing else.
if you want to redirect, you'll want to do that with JS but with no context variables from django.
see this ref
I have a little bit of jQuery on my page which needs to access one of my Django Models. Basically it's a form autocomplete, and it needs to look up values in my database.
I understand how to get values into a Django Template, but getting them into some Javascript code is confusing.
Is this possible? How can it be done?
Thank you.
This link has everything you need. The code is properly written and easy to understand. You can use the values of your model/table to be auto populated in the input field. Check from this link.
def get_Datas(request):
if request.is_ajax():
q = request.GET.get('term', '')
Datas = DataModel.objects.filter(short_name__icontains = q )[:20]
results = []
for Data in Datas:
Data_json = {}
Data_json['value'] = Data.short_name
results.append(Data_json)
data = json.dumps(results)
else:
data = 'fail'
mimetype = 'application/json'
return HttpResponse(data, mimetype)
And use this in template,
<link rel="stylesheet" href="http://code.jquery.com/ui/1.8.18/themes/base/jquery-ui.css" type="text/css" media="all" />
<div class="ui-widget">
<label for="datas">datas: </label>
<input id="datas">
</div>
And the script would be:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript">
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
<script>
$(function() {
$("#datas").autocomplete({
source: "/get_Datas/",
minLength: 1,
});
});
</script>
I recently started to learn jQuery and right now I am playing around with .ajax() function.
I cannot figure out how to access the get parameters in Django.
My code looks like:
Jquery & html:
<div id="browser">
<ul>
{% comment %}
Theres a script for each ctg. Each script fades out #astream, fades in #stream_loading and then it should display #astream with new values based on the GET param in ajax call
Prolly it wont work, but first I need to interact with the GET param in my views.py
{% endcomment %}
{% for ctg in ctgs %}
<script type="text/javascript" charset="utf-8">
(function($) {
$(document).ready(function() {
$("#stream_loading").hide()
$("#browse_{{ctg}}").click(function() {
$("#astream").fadeOut()
$("#stream_loading").fadeIn()
$.ajax({
type: "GET",
url: "/{{defo}}/?param={{ctg}}",
success: function() {
$("#stream_loading").fadeOut()
$("#astream").fadeIn()
}
});
});
});
})(jQuery);
</script>
<li><a id="browse_{{ctg}}" title="{{ctg}}">{{ctg}}</a></li>
{% endfor %}
</ul>
</div>
<div id="astream">
{{ajaxGet}} #just to see whats rendered
{% include "astream.html" %}
</div>
<div id="stream_loading">
loading stream, please wait ...
</div>
Django:
#https_off
def index(request, template='index.html'):
request.session.set_test_cookie()
path=request.META.get('PATH_INFO')
defo=path[1:path[1:].find('/')+1]
request.session['defo']=defo
defo=request.session['defo']
# build the stream sorted by -pub_date
import itertools
chained=itertools.chain(
model1.objects.order_by('-pub_date').filter(),
model2.objects.order_by('-pub_date').filter(),
)
stream=sorted(chained, key=lambda x: x.pub_date, reverse=True)
ajaxGet=request.GET.get('param','dummy')
if request.is_ajax():
template='astream.html'
ajaxGet=request.GET.get('param',False)
renderParams={'defo':defo, 'stream':stream, 'ajaxGet':ajaxGet}
return render_to_response(template, renderParams, context_instance=RequestContext(request))
Then I try to show it up in my template
{{ ajaxGet }}
But everytime is rendered as 'dummy'
In firebug I can see get requests with proper key and value.
What do I miss here?
Thanks
There is a frequent gotcha that people often fall into when doing this kind of Ajax, and that is not preventing the default action of the link/button. So your Ajax function never has a chance to fire, and the request that you're seeing in the Django code is caused by the normal page load - which is why is_ajax() is false.
Give the click handler a parameter, event, and call event.preventDefault(); at the end of the function.
I am new to Django, Ajax and HTML. I am currently developing a simple website for learning purposes.
The site fetches recent news from my db and displays the 5 latest news entry. This should be done without the user refreshing the whole page.
The code below may not seem much, but it is the the result of a painfully long learning process from my end.
Question comes at the end.
url.py
site_media = '/django/feed/site_media/'
urlpatterns = patterns('',
(r'^$', 'recent.views.recent_feed_view'),
# Site media
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': site_media}),)
models.py
class news(models.Model):
question = models.CharField(max_length=200)
pub_date = models.DateField('date published')
views.py
def recent_feed_view(request):
show_results = False
new_feed = []
if 'get_feed' in request.GET:
show_results = True
new_feed = news.objects.order_by('-pub_date')[:5]
variables = RequestContext(request, {
'new_feed': new_feed,
'show_results': show_results,})
if request.GET.has_key('ajax'):
return render_to_response('feed_list.html', variables)
else:
return render_to_response('recent_news.html', variables)
recent_news.html
<html>
<head>
<script type="text/javascript" src="/site_media/jquery.js"> </script>
<script type="text/javascript"src="/site_media/get_feed.js"></script>
</head>
<body>
<form id="search_feed_form" method="get">
<input name = "get_feed" type="submit" value="get_feed" />
</form>
<div id="get_feed_div">
{% if show_results %}
{% include "feed_list.html" %}
{% endif %}
</div>
</body>
</html>
feed_list.html
<ol class="news">
{% for news in new_feed %}
{{ news.question }}
<br />
{% endfor %}
</ol>
get_feed.js
function get_feed_js() {
$('#get_feed_div').load('/?ajax&get_feed');
return false;}
$(document).ready(function () {
$('#search_feed_form').submit(get_feed_js);});
Questions:
1- How can I modify my javascript function so that the page automatically fetches the latest news feed, say every 1 min, without having to press the button?
2- Is there a way to fetch the latest news feed when the user navigates to my website tab? (i.e.: he was currently viewing another tab on his browser and just clicked on the tab with my site on it)
I would greatly appreciate it if I could receive some tips / links to useful materiel that can help me move forward in this endeavor!
Use setInterval: http://www.elated.com/articles/javascript-timers-with-settimeout-and-setinterval/
setInterval('get_feed_js()', 60000); // call func every 60 seconds
$(window).one('focus', function() { // without one, I infinitely get focus event
get_feed_js(); // call function on tab focus
})