How can I add a Bar Chart to my Django based Database? - python

Dear community members,
I really hope that you will help me to add a Bar Graph to my Django project.
1. I have a Database with around 1000 items.
2. I need to be able visualise a 3 month sales for each item when needed.
Not sure what is a correct approach.
here is my models.py:
from django.db import models
from math import *
from decimal import *
class Itemslist(models.Model):
item_n = models.CharField(max_length=200)
sales_this_month = models.DecimalField(blank=True, null=True, max_digits=19,
decimal_places=0)
saleslm = models.DecimalField(blank=True, null=True, max_digits=19, decimal_places=0)
sales2m = models.DecimalField(blank=True, null=True, max_digits=19, decimal_places=0)
sales3m = models.DecimalField(blank=True, null=True, max_digits=19, decimal_places=0)
def __str__(self):
return self.item_n
here is my views.py file, that as an experiment I have created, using the last solution provided:
def charts(request):
charts = Itemslist.objects \
.values('saleslm') \
.annotate(lm=Count('saleslm')) \
.annotate(m2=Count('sales2m')) \
.annotate(3m3=Count('sales3m')) \
.order_by('saleslm')
return render(request, 'charts.html', {'charts': charts})
As you can see, this is not a solution I need, I was just trying to come up with at least something , and eaven that has shown me the graph with the same values.
here is my hmtl code:
{% extends 'base.html' %}
{% block js %}
{% if user.is_authenticated %}
{% load loads_extra %}
{% load static %}
<br>
<p>Logged in user: {{ user.username }}</p>
<br>
<html>
<head>
<meta charset="utf-8">
<title>Django Highcharts Example</title>
</head>
<body>
<div id="container"></div>
{
<script src="https://code.highcharts.com/highcharts.src.js"></script>
<script>
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Sales previous 3 months'
},
xAxis: {
categories: ['sales']
},
series: [{
name: '3mBack',
data: [ {% for entry in charts %}{{ entry.m3 }}{% endfor %} ]
}, {
name: '2mBack',
data: [ {% for entry in charts %}{{ entry.m2 }}{% endfor %} ]
}, {
name: 'Lmonth',
data: [ {% for entry in charts %}{{ entry.lm }}{% endfor %} ]
}, ]
});
</script>
</body>
</html>
{% endif %}
{% endblock %}
<!-- charting tutorial to follow : https://simpleisbetterthancomplex.com/tutorial/2018/04/03/how-to-integrate-highcharts-js-with-django.html -->
I have to create a request button for charts and then chart has to be generated with a right parameters.
Have looked at this question:
Displaying multiple bar graph in django
Also have searched through this solution
https://code.djangoproject.com/wiki/Charts
And looked at this article
https://simpleisbetterthancomplex.com/tutorial/2018/04/03/how-to-integrate-highcharts-js-with-django.html
The last article was the clearest one, and you can see, that I have just copy pasted the solution from there, with small changes.
here is a script that I have placed in my base.html file:
<script src="https://code.highcharts.com/highcharts.src.js"></script>
and that's the chart that I have finally got displayed:
But still can’t find how to deal with it in my situation.
All this solutions, as far as I can see, are showing how to implement charting to one array, or to sum or self generated array. But I want to be able to chose, when to show a graph and for which Item.
the button is placed on this html file:
{% extends 'base.html' %}
{% block js %}
{% if user.is_authenticated %}
{% load loads_extra %}
{% load static %}
<br>
<p>Logged in user: {{ user.username }}</p>
<br>
<body>
<table id="example" class="table table-striped table-bordered dt-responsive nowrap" style="width:100%">
<thead>
<tr>
<th>SUP:</th>
<th>Item N.:</th>
<th>SKU</th>
<th>Description</th>
<th>3mBack</th>
<th>2mBack</th>
<th>Lmonth</th>
<th>CMonth</th>
<th>Nmonth</th>
<th>N2Month</th>
<th>N3month</th>
<th></th>
</tr>
</thead>
<tbody>
{% for records in sorted %}
<tr>
<td>{{ records.sup }}</td>
<td>{{ records.item_n }}</td>
<td>{{ records.sku }}</td>
<td>{{ records.description }}</td>
<td>{{ records.sales3m }}</td>
<td>{{ records.sales2m }}</td>
<td>{{ records.saleslm }}</td>
<td>{{ records.sales_this_month }}</td>
<td>{{ records.m1predicted }}</td>
<td>{{ records.m2predicted }}</td>
<td>{{ records.m3predicted }}</td>
<td>
Edit
</td>
</tr>
{% endfor %}
</tbody>
</table>
<script>
$(document).ready(function() {
var table = $('#example').DataTable( {
fixedColumns: true,
lengthChange: true,
buttons: [ 'copy', 'excel', 'csv', 'pdf', 'colvis' ]
} );
table.buttons().container()
.appendTo( '#example_wrapper .col-md-6:eq(0)' );
} );
</script>
</body>
</html>
{% endif %}
<div></div>
{% endblock js %}
This is my first question in this community, so if something is not clear, please help me to correct it in a right way.
waiting for any helpful answers!!!

Good News community.
I have been offered a very good solution, and now my question is completely sorted.
At least for my needs, this is a perfect solution.
instead of highcharts, I have been offered to use d3js.org, which is absolutely fine for me.
The logic behind a code is that you request data from the values displayed, hopefully it will be clear, when you will go through the code with comments.
as it's a django project, here's the heading of my html file:
{% extends 'base.html' %}
{% block js %}
{% if user.is_authenticated %}
{% load loads_extra %}
{% load static %}
<br>
<p>Logged in user: {{ user.username }}</p>
<br>
here is a part of my html code that displays table/value:
<table id="example" class="table table-striped table-bordered dt-responsive nowrap" style="width:100%">
<thead>
<tr>
<th>SUP:</th>
<th>Item N.:</th>
<th>SKU</th>
<th>Description</th>
<th>6mBack</th>
<th>5mBack</th>
<th>4mBack</th>
<th>3mBack</th>
<th>2mBack</th>
<th>Lmonth</th>
<th>CMonth</th>
<th>Nmonth</th>
<th>N2Month</th>
<th>N3month</th>
<th>AVGrowth</th>
<th></th>
<!-- This is header for new button to draw the Bar Charts -->
<th></th>
</tr>
</thead>
<tbody>
{% for records in sorted %}
<tr>
<td>{{ records.sup }}</td>
<td>{{ records.item_n }}</td>
<td>{{ records.sku }}</td>
<td>{{ records.description }}</td>
<td>{{ records.sales6m }}</td>
<td>{{ records.sales5m }}</td>
<td>{{ records.sales4m }}</td>
<td>{{ records.sales3m }}</td>
<td>{{ records.sales2m }}</td>
<td>{{ records.saleslm }}</td>
<td>{{ records.sales_this_month }}</td>
<td>{{ records.m1predicted }}</td>
<td>{{ records.m2predicted }}</td>
<td>{{ records.m3predicted }}</td>
<td>{{ records.avgrowths }}</td>
<td>
Edit
</td>
<!-- Add new button for drawing Bar Charts -->
<td>
<button class="btn btn-secondary" onclick="draw_chart(this)" data-toggle="modal" data-target="#myModal">Chart</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
please read comments to understand what is what.
and here is the rest of html, that is generating a chart on a topup window,by pressing a button in front of an array that has to be visualised:
<!-- Modal which Bar Chart will be placed -->
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog" style="max-width: 900px !important">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body">
<!-- <svg> element which will contains the Bar Chart -->
<svg width="1000" height="500"></svg>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- Insert D3.js Library -->
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
$(document).ready(function() {
var table = $('#example').DataTable( {
fixedColumns: true,
lengthChange: true,
buttons: [ 'copy', 'excel', 'csv', 'pdf', 'colvis' ]
} );
table.buttons().container()
.appendTo( '#example_wrapper .col-md-6:eq(0)' );
} );
// Main functions for Drawing Bar chart using D3.js
function draw_chart(item){
// `item` is the current clicked button element
// `row_ele` is the parent <tr> element of the current clicked button element
row_ele = item.closest('tr');
// Get the value from the <td> element using nth-child()
val_6mBack = row_ele.querySelector("td:nth-child(5)");
val_5mBack = row_ele.querySelector("td:nth-child(6)");
val_4mBack = row_ele.querySelector("td:nth-child(7)");
val_3mBack = row_ele.querySelector("td:nth-child(8)");
val_2mBack = row_ele.querySelector("td:nth-child(9)");
val_Lmonth = row_ele.querySelector("td:nth-child(10)");
val_CMonth = row_ele.querySelector("td:nth-child(11)");
val_Nmonth = row_ele.querySelector("td:nth-child(12)");
val_N2Month = row_ele.querySelector("td:nth-child(13)");
val_N3month = row_ele.querySelector("td:nth-child(14)");
// `data` is variable which store the data for Bar Charts
data = []
// Pushing data as key/value type objects into the `data` variable
data.push({'label':'6mBack', 'value': val_6mBack.innerHTML})
data.push({'label':'5mBack', 'value': val_5mBack.innerHTML})
data.push({'label':'4mBack', 'value': val_4mBack.innerHTML})
data.push({'label':'3mBack', 'value': val_3mBack.innerHTML})
data.push({'label':'2mBack', 'value': val_2mBack.innerHTML})
data.push({'label':'Lmonth', 'value': val_Lmonth.innerHTML})
data.push({'label':'CMonth', 'value': val_CMonth.innerHTML})
data.push({'label':'Nmonth', 'value': val_Nmonth.innerHTML})
data.push({'label':'N2Month', 'value': val_N2Month.innerHTML})
data.push({'label':'N3month', 'value': val_N3month.innerHTML})
// Set <svg> element's width and height
var svg = d3.select("svg"),
margin = 200,
width = svg.attr("width") - margin,
height = svg.attr("height") - margin
// Remove the old contents of the <svg> element
svg.selectAll('*').remove()
// Initialize X-axis and Y-axis for Bar Chart
var xScale = d3.scaleBand().range([0, width]).padding(0.4),
yScale = d3.scaleLinear().range([height, 0]);
// Set all group which is placed in the <svg>element
// transform to (50,100) on <svg> area , margint in svg has been changed to 300 and instead 50/100, changed to 100/300, but then back.
var g = svg.append("g")
.attr("transform", "translate(" + 50 + "," + 100 + ")");
xScale.domain(data.map(function(d) { return d.label; }));
// If all values of data will be zero, we will fix the range of the Y-axis
if(d3.max(data, function(d) { return d.value; }) == 0){
yScale.domain([0, 10]);
}else{
// If all is not zero, we will set Y-axis from 0 to maximum value.
yScale.domain([0, d3.max(data, function(d) { return Number(d.value); })]);
}
// Set X- axis
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(xScale));
// Set Y-axis using ticket
g.append("g")
.call(d3.axisLeft(yScale).tickFormat(function(d){
return d;
}).ticks(10));
console.log(data)
// Draw Bar Chart using <rect> element by data which is stored in the `data` variable
g.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return xScale(d.label); })
.attr("y", function(d) { return yScale(d.value); })
.attr("width", xScale.bandwidth())
.attr("height", function(d) { return height - yScale(d.value); })
.style('fill','#899da6');
}
</script>
</body>
{% endif %}
{% endblock js %}
so finally here is how my html looks like live:
and here is a graph, that I get by pressing chart button:
in order to help community, please ask questions, and please add/correct if there is a better way.
Thank you very much for your help and attention!!!

views.py
You have an error on annotate(3m3 its cannot start with 3 here. You also have same function name and variable name def charts and charts inside. Python might be smart enough to figure it out but try to avoid doing this. I am also against naming variables saleslm and sales2m be explicit here.
def charts(request):
return render(request, 'charts.html')
def charts_ajax(request):
charts_data = Itemslist.objects \
.values('saleslm') \
.annotate(lm=Count('saleslm')) \
.annotate(m2=Count('sales2m')) \
.annotate(m3=Count('sales3m')) \
.order_by('saleslm')
return JsonResponse({'charts': list(charts_data)})
url.py
path('charts/', views.charts, name='charts_home'),
path('charts_ajax/', views.charts_ajax, name='render_charts_ajax')
html
You have multiple issues in your html file.
</html>
{% endif %}
<div></div>
{% endblock js %}
You have div after the html has ended. You should not have anything after html ends.
Few other organizational issues here. I usually would have a block content and then block js while you have everything inside block js. I would clean those. Now that you added datables also. You can add buttons as mentioned here. https://datatables.net/extensions/buttons/examples/initialisation/custom.html
but if i were you i would try to make it work with simple table and move on to datables.
<html>
<head>
<meta charset="utf-8">
<title>Django Highcharts Example</title>
</head>
<body>
<div id="container">
</div>
<button id="render_chart" type="button">Render Chart</button>
<script
src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous"></script>
<script src="https://code.highcharts.com/highcharts.src.js"></script>
<script>
$(document).ready(function(){
$('#render_chart').on('click', function(e){
$.ajax({
url: "{% url 'render_charts_ajax'%}",
type: "GET",
dataType: "json",
success: function (data) {
console.log(data.charts[0].saleslm)
Highcharts.chart('container',{
chart:{
type:'bar'
},
title:{
text:"Sales Last Month"
},
series:[{
name:"Sales LM",
data:[parseInt(data.charts[0].saleslm)]
}]
})
}
})
})
});
</script>
</body>
</html>
Your json might need some processing before the chart comes out right.

Related

How to render results from groupby query in html - Django

I'm trying to render results of a group by query from a view to an HTML table but it is returning nothing. I originally had success in listing all results, but after applying the sum aggregation I can't get it to appear.
Django View - with Group By
def get_asset_price(request):
# CryptoAssets is the model
obj = CryptoAssets.objects.filter(user_id=request.user.id).values('symbol')
obj = obj.annotate(total_units=Sum('units'),
total_cost=Sum('cost'))\
.order_by('symbol')
# Returns list of dictionaries
context = {
'object': obj
}
return render(request, 'coinprices/my-dashboard.html', context)
HTML
<style>
table, th, td {
border: 1px solid black;
}
</style>
<div class="container">
<h1>My Dashboard</h1>
<table>
<tr>
<th>Symbol</th>
<th>Total Units</th>
<th>Total Cost</th>
</tr>
{% for row in object %}
<tr>
<td>{{ row.symbol }}</td>
<td>{{ row.units }}</td>
<td>{{ row.cost }}</td>
</tr>
{% endfor %}
</table>
</div>
{% endblock %}
I'll provide the view below that worked without the group by.
Django View - No group by
def get_asset_price(request):
# CryptoAssets is the model
obj = CryptoAssets.objects.all().filter(user_id=request.user.id)
# Returns list of objects
context = {
'object': obj
}
return render(request, 'coinprices/my-dashboard.html', context)
I think you're calling an attribute which does not exist on your object. The type of your object is a list of dictionaries. Change your template codes to something like this (this is the simplest way and maybe you can improve it later like adding a template tag similar to the one that is used in this question):
<table>
<tr>
<th>Symbol</th>
<th>Total Units</th>
<th>Total Cost</th>
</tr>
{% for row in object %}
<tr>
{% for key, value in row.items %}
<td>{{ key }}</td>
<td>{{ value }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>

Not able to send checkbox data from all pagination in datatable from template to view in django

I have a datatable in my django template in which there is a checkbox next to every row to send the row data to a view function to make some mass updations in django model. But problem is if the multiple rows are on the same page in pagination then i can send the data accurately BUT if i select row 2 from page 1 and row 5 from page 3 only the row value from page 3 will be sent to the view function.!
TEMPLATE.HTML
{% block jquery %}
<script type="text/javascript" class="init">
$(document).ready( function ($) {
var $submit = $("#updiv").hide(),
$cbs = $('input[name="updelegate"]').click(function() {
$submit.toggle( $cbs.is(":checked") );
});
$('#myTable').DataTable({
dom: 'lBfrtip',
"pageLength": 1,
"language": {
"emptyTable": "No Delegates Available",
"sSearch": "Search Delegates: ",
"info": " Showing _START_-_END_ out of Total _TOTAL_ Delegates",
}
});
});
</script>
{% endblock %}
<form id="myForm" action="{% url 'mass-delegates' %}" method="POST">
{% csrf_token %}
<table id="myTable" class="table table-striped table-bordered" style="width:100%">
<thead class="thead-dark">
<tr>
<th></th>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Email</th>
<th scope="col">Phone</th>
<th scope="col">Company</th>
<th scope="col">Designation</th>
<th scope="col">Address</th>
<th scope="col">City</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{% for del in delegates %}
<tr>
<td>
<label class="container">
<input type="checkbox" id="updelegate" name="updelegate"
value="{{ del.id }}">
<span class="checkmark"></span>
</label>
</td>
<td>{{ del.id }}</td>
<td>{{ del.first_name }} {{ del.last_name }}</td>
<td>{{ del.email }}</td>
<td>{{ del.phone }}</td>
<td>{{ del.company }}</td>
<td>{{ del.designation }}</td>
<td>{{ del.address }}</td>
<td>{{ del.city }} ({{ del.pincode }})</td>
<td>
View
</td>
<td>
Edit
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div id="updiv">
<select name="eventid">
{% for ev in events %}
<option value="{{ ev.id }}">{{ ev.name }}</option>
{% endfor %}
</select>
<input type="submit" onclick="return confirm('Confirm Adding to Event?');" class="upbtn"
name="update" value="Add to Event"/>
</div>
</form>
VIEW.PY
def mass_delegates(request):
if request.method == 'POST':
toupdate = request.POST.getlist('updelegate')
eventid = request.POST.get('eventid')
array_length = len(toupdate)
for i in range(array_length):
if not EventDelegate.objects.filter(event_id=eventid, delegate_id=toupdate[i]).exists():
EventDelegate.objects.create(event_id=eventid, delegate_id=toupdate[i])
return event_det(request, eventid)
Instead of using the checkboxes, you can directly use the select attribute in the Datatables api. Check Select Rows in Datatables
Moreover, Since you want to select multiple rows at once, you might consider checking Multi Select rows in Datatables out
You can add the id in the 0th column, then
dataTable = $(.selector).Datatable()
dataTable.columns([0]).visible(false);
You can hide the column like that and then when you send your request, you still have your id

Django/Python : Sort python's dictionaries with the equals key

I am currently trying to sort two Python dictionaries into an HTML array such as:
#Headers
DictA = {'value': 'valeur', 'name': 'nom' }
#Data
DictB = {'value': '456', 'name': 'Test' }
I wanted to sort these two dictionaries in order to get the '456' in DictB equals to the key 'value' in DictA.
Note: I used other dictionaries than DictA and DictB, it was just an example. But it fits my problem.
In my views.py, I define my two dictionaries such as:
headers = json.loads(entries[0].form_data_headers)
data = json.loads(entries[1].saved_data)
valuesData = data.values()
then I pass them into the template.html via the context:
context = {'entries': entries, 'form_entry_id': form_entry_id, 'headers': headers, 'data': data, 'valuesData': valuesData}
Thus, in my template, it will print an array with the headers (DictA) and the datas (DictB).
In my template I make this code:
<thead>
<!-- Test pr voir si les values sont pris en compte ou non -->
<p>{{valuesData}}</p>
<tr>
{% for entry in headers %}
<td>
{{ entry }}
</td>
{% endfor %}
</tr>
</thead>
And the datas are in another for loop:
<tbody>
<thead>
<!-- Test pr voir si les values sont pris en compte ou non -->
<p>{{valuesData}}</p>
<tr>
{% for entry in dataValues %}
<td>
{{ entry }}
</td>
{% endfor %}
</tr>
</thead>
</tbody>
The result is kinda such as follow:
name equals 456 (instead of the name of the form)
geom equals test (instead of my coordinate)
etc.
It doesn't match the right header.
I was thinking about making two for loops with an if statement in it:
{%if headers['name'] == dataValues['name']%}
<td>dataValues['name']</td>
But I get an error as dataValues['name'] could not be parsed.
The rest of the code is in Javascript:
{% endblock content %}
{% block javascript %}
<script type="text/javascript">
function GetURLParameter(param_name){
var sPageURL = window.location.search.substring(1);
var sParameterName = sPageURL.split('=');
return sParameterName[1];
}
var name= GetURLParameter(name);
document.querySelector('.page-header .value').innerHTML = name;
</script>
{% endblock %}
{% block main-content-inner-attrs %}
{% endblock main-content-inner-attrs %}
{% block sidebar-wrapper %}
{% endblock sidebar-wrapper %}
The rest of the code is in javascript :
{% endblock content %}
{% block javascript %}
<script type="text/javascript">
function GetURLParameter(param_name){
var sPageURL = window.location.search.substring(1);
var sParameterName = sPageURL.split('=');
return sParameterName[1];
}
var name= GetURLParameter(name);
document.querySelector('.page-header .value').innerHTML = name;
</script>
{% endblock %}
{% block main-content-inner-attrs %}
{% endblock main-content-inner-attrs %}
{% block sidebar-wrapper %}
{% endblock sidebar-wrapper %}
Here is the right answer :
<tr>
{% for cle, valeur in headersLoop %}
{% for cleVD, valeurVD in valuesData %}
{% if cle == cleVD %}
<td>
<p> {{cle}}{{valeurVD}} </p>
</td>
{% endif %}
{% endfor %}
{% endfor %}
</tr>
I marked it as solved. And create a new topic. Thanks all.

Finding the sum of numbers in jinja2 template using flask

I am learning flask and tried to create a web app that accepts a student's name and marks, finds the total of all the marks and display things in a table. But the total always gets displayed as 0.
The code is given below
mark_total.py:
from flask import Flask, render_template, request
app = Flask (__name__)
#app.route('/')
def student():
return render_template('student.html')
#app.route('/result', methods = ['POST', 'GET'])
def result():
if request.method == 'POST':
result = request.form
return render_template('result.html', result = result)
if __name__ == '__main__':
app.run(host = '0.0.0.0', debug = True)
student.html:
<form action = "/result" method = "POST">
<p>Name <input type = "text" name = "Name" /></p>
<p>Physics <input type = "text" name = "Physics" /></p>
<p>Chemistry <input type = "text" name = "chemistry" /></p>
<p>Maths <input type ="text" name = "Mathematics" /></p>
<p><input type = "submit" value = "submit" /></p>
</form>
</body>
</html>
result.html:
<html>
<head>
<title>Results</title>
</head>
<body>
<h1>{{result["Name"]}}'s results</h1>
{% set total = 0 %}
<table border = 1>
{% for key, val in result.iteritems() %}
{% if key != 'Name' %}
{% set total = total|int + val|int %}
<tr>
<td>{{ key }}</td>
<td>{{ val }}</td>
<td>{{ total }}</td>
</tr>
{% endif %}
{% endfor %}
<tr>
<td>Total</td>
<td>{{total}}</td>
</tr>
</table>
</body>
</html>
The html source of the output is as follows:
<html>
<head>
<title>Results</title>
</head>
<body>
<h1>ABC's results</h1>
<table border = 1>
<tr>
<td>Mathematics</td>
<td>100</td>
<td>100</td>
</tr>
<tr>
<td>chemistry</td>
<td>100</td>
<td>100</td>
</tr>
<tr>
<td>Physics</td>
<td>100</td>
<td>100</td>
</tr>
<tr>
<td>Total</td>
<td>0</td>
</tr>
</table>
</body>
</html>
Can someone please help me understand how to solve this?
The problem is that your total defined inside the loop is not the same total defined (and accessed) outside of loop. This is what local scopes do.
You can overcome this by using a hack like this (adapted from this answer).
<html>
<head>
<title>Results</title>
</head>
<body>
<h1>{{result["Name"]}}'s results</h1>
{% set total = [0] %}
<table border = 1>
{% for key, val in result.iteritems() %}
{% if key != 'Name' %}
{% set _ = total.append(total.pop() + val|int) %}
<tr>
<td>{{ key }}</td>
<td>{{ val }}</td>
<td>{{ total[0] }}</td>
</tr>
{% endif %}
{% endfor %}
<tr>
<td>Total</td>
<td>{{ total[0] }}</td>
</tr>
</table>
</body>
</html>
But I'm really not sure that it is a good idea to do such things in a template. The main idea of templates is to separate the logic (like counting the totals) and the representation, and this is a violation of this principle.
When you change variable value inside a loop does not effect outside of the loop except a dict:
{% set total = {'value': 0} %}
...
{% if total.update({"value": c|int + total.value|int }) %} {% endif %}
...
{{total.value}}

Search from database using ajax in django

I am working on a django project and making a dashboard in which I am trying to add a search bar in which on typing I will get a list of all the relevant searches.
Views.py
def get_user_name(request):
if request.is_ajax():
results = []
context = RequestContext(request)
if request.method == 'GET':
q = request.GET.get('search_text')
results = User.objects.filter(user_name__contains = q)
context = {
'data': []
}
for record in results:
data = {
'id': record.id,
'code': record.code,
'name': record.name,
'manager': record.manager.email,
'type': record.type.upper(),
'status': record.current_state.display_name,
}
return render(request, 'listinguser.html', context)
listinguser.html
{% extends "base.html" %}
{% block title %}Users Listing Page{% endblock %}
{% block body %}
<div class='page_header'>
<div class="ui-widget">
<p align="right">
<input type="text" placeholder="Type user name" id="user_name" name="term">
</p>
</div>
<script>
$("#user_name").keypress(function(){
$.ajax({
type: "GET",
url: "{% url "user_name" %}",
data: {
'search_text' : $('#chain_name').val(),
'csrfmiddlewaretoken' : $("input[name=csrfmiddlewaretoken]").val()
},
dataType: "json",
success: function(response) {
//success code
},
error: function(rs, e)
alert(rs.responseText);
}
});
})
</script>
</div>
<div class="col-md-6" style="width:100%">
<table id="data-table" class="table table-striped table-bordered">
<thead>
<tr>
<th style="width: 5%;">#</th>
<th style="width: 8%;">Id</th>
<th style="width: 15%;">Name</th>
<th style="width: 15%;">Status</th>
</tr>
</thead>
<tbody>
{% for record in data %}
<tr>
<td>{{ forloop.counter}}</td>
<td>{{ record.user_id }}</td>
<td>{{ record.user_name }} <br>({{ record.user_type }})</td>
<td>{{ record.user_status }}</td>
{% endfor %}
</tbody>
</table>
{% if page.has_other_pages %}
<ul class="pagination">
{% if page.has_previous %}
<li>«</li>
{% else %}
<li class="disabled"><span>«</span></li>
{% endif %}
{% for i in page.paginator.page_range %}
{% if page.number == i %}
<li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
{% else %}
<li>{{ i }}</li>
{% endif %}
{% endfor %}
{% if page.has_next %}
<li>»</li>
{% else %}
<li class="disabled"><span>»</span></li>
{% endif %}
</ul>
{% endif %}
</div>
{% endblock %}
Problem I am facing:
While I type something in the search box the ajax func is called but it always goes into the error block.
Also I want the search result to get populated in the table just as the table normally is.
This is the API which I use to populate the table.
class UserListingView(View):
def get(self, request):
try:
page_size = int(request.GET.get('page_size', 10))
page_no = int(request.GET.get('page_no', 1))
except ValueError:
# Set the default value
page_size = 100
page_no = 1
filter_on = request.GET.get('current_state', None)
if 'listing_user' in request.user.permissions:
users = Users.objects.select_related(
"user", "user_state", "user_manager"
).all()
else:
users = User.objects.select_related(
"user", "user_state", "user_manager"
).filter(user_manager=request.user)
paginator = Paginator(integrations, page_size)
context = {
'page': {},
'data': []
}
try:
page = paginator.page(page_no)
context['current_page'] = page_no
except EmptyPage:
# Show the last page
page = paginator.page(paginator.num_pages)
context['current_page'] = paginator.num_pages
for record in page:
data = {
'user_id': record.id,
'user_code': record.user_code,
'user_id': record.user_id,
'user_name': record.user_name,
'user_manager': record.user_manager.email,
'user_type': record.user_type.upper(),
'user_status': record.user_state.display_name,
'user_status': user_status,
}
context['data'].append(data)
context['page'] = page
return render(request, 'listinguser.html', context)

Categories

Resources