I am trying to use django with pandas for data analysis. There seem to be no simple step by step tutorial on this. All the ones i have seen online just explain how to write the code in your django views.py
file but none shows how to display the final product in the browser.
Here is the code in my views.py
def index2(request):
qs = Product.objects.all()
df = read_frame(qs)
html= df.to_html
return HttpResponse(html)
but this does not work. Any detailed help will be appreciated. Please dont just point me to some documentation. In fact, most of django's documentation is not written in simple plain english --- it is even more confusing to some of us. Thank you.
Pandas in Python has the ability to convert Pandas DataFrame to a table in the HTML web page. pandas. DataFrame. to_html() method is used for render a Pandas DataFrame.
How do you pass a Python variable to a template? And this is rather simple, because Django has built-in template modules that makes a transfer easy. Basically you just take the variable from views.py and enclose it within curly braces {{ }} in the template file.
You cannot use python code in django template. This is by design, Django's idea of template is to isolate the presentation logic from the programming code.
Here is a minimal but elegant solution using Django_Pandas and an 'extended Bootstrap table' (https://github.com/wenzhixin/bootstrap-table)
The elegance comes from the ability to export a Pandas DataFrame to JSON, and for the Bootstrap Table script to consume that JSON content.
The HTML table is written for us, we don't need to worry about it (look below where we just include the 'table' tag without writing the rows ourselves, or even a for loop.) And it's interactive. And Bootstrap makes it look pretty.
requirements: Bootstrap, JQuery, Django_Pandas, wenzhixin/bootstrap-table
models.py
from django.db import models
from django_pandas.managers import DataFrameManager
class Product(models.Model):
product_name=models.TextField()
objects = models.Manager()
pdobjects = DataFrameManager() # Pandas-Enabled Manager
views.py
from models import Product
def ProductView(request):
qs = Product.pdobjects.all() # Use the Pandas Manager
df = qs.to_dataframe()
template = 'product.html'
#Format the column headers for the Bootstrap table, they're just a list of field names,
#duplicated and turned into dicts like this: {'field': 'foo', 'title: 'foo'}
columns = [{'field': f, 'title': f} for f in Product._Meta.fields]
#Write the DataFrame to JSON (as easy as can be)
json = df.to_json(orient='records') # output just the records (no fieldnames) as a collection of tuples
#Proceed to create your context object containing the columns and the data
context = {
'data': json,
'columns': columns
}
#And render it!
return render(request, template, context)
product.html
<script src='/path/to/bootstrap.js'>
<script src='/path/to/jquery.js'>
<script src='/path/to/bootstrap-table.js'>
<script src='/path/to/pandas_bootstrap_table.js'>
<table id='datatable'></table>
<!-- Yep, all you need is a properly identified
but otherwise empty, table tag! -->
pandas_bootstrap_table.js
$(function() {
$('#datatable')({
striped: true,
pagination: true,
showColumns: true,
showToggle: true,
showExport: true,
sortable: true,
paginationVAlign: 'both',
pageSize: 25,
pageList: [10, 25, 50, 100, 'ALL'],
columns: {{ columns|safe }}, // here is where we use the column content from our Django View
data: {{ data|safe }}, // here is where we use the data content from our Django View. we escape the content with the safe tag so the raw JSON isn't shown.
});
});
to_html
is a function, you have to call it.
def index2(request):
df = read_frame(Product.objects.all())
return HttpResponse(df.to_html())
#app/models.py
from django.db import models
class Consumer(models.Model):
username = models.CharField(max_length=100, null=True)
phone = models.BigIntegerField(null=True)
first_name = models.CharField(max_length=100, null=True)
last_name = models.CharField(max_length=100, null=True)
def __str__(self):
return self.first_name
#app/views.py
from django.shortcuts import render
import pandas as pd
from .models import Consumer
import json
def ConsumerView(request):
qs = Consumer.objects.all()
consumers = [{"UserName":x.username,"FirstName":x.first_name,"LastName":x.last_name} for x in qs]
df = pd.DataFrame(consumers)
# parsing the DataFrame in json format.
json_records = df.reset_index().to_json(orient ='records')
data = []
data = json.loads(json_records)
context = {'d': data}
return render(request, "CR.html", context)
#app/urls.py
from django.urls import path
from .views import ConsumerView
urlpatterns = [
path('',ConsumerView, name='CR'),
]
#templates/CR.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Django-Pandas-Template</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<h2 class="text-center"><u>Django models --> Pandas DataFrame --> render to --> Templates(.html) </u></h2><br>
<table class="table table-dark table-striped">
<thead>
<tr>
<th>User Name</th>
<th>First Name</th>
<th>Last Name</th>
</tr>
</thead>
<tbody>
<!-- jinja2 Technique -->
{% if d %}
{% for i in d %}
<tr>
<td>{{i.UserName}}</td>
<td>{{i.FirstName}}</td>
<td>{{i.LastName}}</td>
</tr>
{% endfor %}
{% endif %}
</tbody>
</table>
</div>
</body>
</html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With