I just want to write a table in HTML in Django, where the data is not from Database. It seems django-tables2 is a good package that I can use in Django. However, my data is not from Database, so maybe it's not necessary to use Django model. Here comes my code of view.py and HTML page:
def device_manager_submit(request):
'''Switch manager page'''
ret = rest.send_device_tor(device_name) #data from rest API exist in the form of array of dictronary: [{}, {}, {}]
return HttpResponse(ret) #return data to HTML
I can use for loop in HTML to display this data but I'm not clearly about how to show them:
<tbody>
{% for item in xx %} //I'm not sure
<tr>
<td>111</td> //how to display?
</tr>
{% endfor %}
Does anyone has any example that I can follow to display the data from view.py in HTML page
You don't need to return Django objects to create templates, you can use any data. The render() function allows you to combine context with the regular HttpResponse. You pass it the request which was given to the view calling it, the name of the template you want to render, and then a dictionary of data to provide to the template.
def device_manager_submit(request):
'''Switch manager page'''
ret = rest.send_device_tor(device_name) #data from rest API exist in the form of array of dictronary: [{}, {}, {}]
return render(request, 'some_template.html', {'devices': ret}) #return data to HTML
Assuming that ret contains some objects with a name and description, we can loop through devices like so:
<tbody>
{% for device in devices %}
<tr>
<td>{{ device.name }}</td>
<td>{{ device.description }}</td>
</tr>
{% endfor %}
One way would be to use pandas to load the data, and then use the DataFrame.to_html() to output the data into an html table. See the example below:
import pandas as pd
data = [{'column1': 1, 'column2': 2}]
df = pd.DataFrame(data)
html = df.to_html()
Html will result in:
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>column1</th>
<th>column2</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>1</td>
<td>2</td>
</tr>
</tbody>
</table>
In a Django view this would be:
#api_view(['GET'])
def showData(request):
data = [{'column1': 1, 'column2': 2}]
df = pd.DataFrame(data)
html = df.to_html()
return HttpResponse(html)
Related
I have modeled my database using models.py within my django project, one of the fields is a JSONField and I can save json data into that field without any problem. My doubt comes in how I can show that information as an html table. At the moment I have been using ListView to show that information in a template but I don't know how to transform it into a table.
If you use object.json_field.items you can loop through them just like a normal dictonary / can also use .keys and .values
Example use in a table
<table>
<thead>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{% for k, v in object.json_field.items %}
<tr>
<th>{{k}}</th>
<th>{{v}}</th>
</tr>
{% endfor %}
</tbody>
</table>
I made only one table in my application. I want to display some information on the page admin.html and
specific user information on info.html page. How should I give the query to show the particular user information on which client has clicked on the admin page. I want to display other attributes of my database like email, phone number, college name only on the info.html page. Here are my files:
database
class database(db.Model):
id=db.Column('user_id',db.Integer, primary_key=True)
name = db.Column(db.String(20))
text=db.Column(db.String(1000))
personality_score=db.Column(db.Integer)
skills_score=db.Column(db.Integer)
experience_score=db.Column(db.Integer)
total_score=db.Column(db.Integer)
college=db.Column(db.String(100))
email=db.Column(db.String(100))
phone_number=db.Column(db.String(100))
app.py
#app.route('/admin')
def admin():
return render_template('admin.html',database=database.query.order_by(database.total_score.desc()).all())
#app.route('/info')
def info():
return render_template('info.html')
admin.html
<table class="css-serial">
<tbody>
<tr>
<th>Rank</th>
<th>ID</th>
<th>Name</th>
<th>Profile Summary</th>
<th>Personality Score</th>
<th>Skills Score</th>
<th>Experience Score</th>
<th>Total Score</th>
</tr><tr>
{% for data in database %}
<td></td>
<td>{{data.id}}</td>
<td><a href=info>{{ data.name }}</a></td>
<td>{{ data.text }}</td>
<td>{{ data.personality_score }}</td>
<td>{{data.skills_score}}</td>
<td>{{data.experience_score}}</td>
<td>{{data.total_score}}</td>
</tr></tbody>
{% endfor %}
</table>
I have not written anything in the info.html file because I was not able to figure out how to fetch 'id' or data to display on that page.
Assuming that I understood your question correctly, here's what you wish to do:
You want to click on the anchor tag on the {{data.name}} and the person should first be redirected to the '/info' route.
On that route, the information associated with the person whose name was clicked is to be showed.
(1) is re-routing concept in flask. For which we use url_for method.
(2) is a basic WHERE query in sqlAlchemy ORM for which we can use the filter_by filter and first() collector.
Your route '/info' should take a parameter, user id, which we will use to filter the user information. Preferably, the info route can be changed as follows:
#app.route('/info/<id>')
def info(id):
user_info = database.query.filter_by(id=id).first()
return render_template('info.html', information=user_info)
Change your admin.html as follows:
<table class="css-serial">
<tbody>
<tr>
<th>Rank</th>
<th>ID</th>
<th>Name</th>
<th>Profile Summary</th>
<th>Personality Score</th>
<th>Skills Score</th>
<th>Experience Score</th>
<th>Total Score</th>
</tr>
<tr>
{% for data in database %}
<td></td>
<td>{{data.id}}</td>
<td>
{{ data.name }}
</td>
<td>{{ data.text }}</td>
<td>{{ data.personality_score }}</td>
<td>{{data.skills_score}}</td>
<td>{{data.experience_score}}</td>
<td>{{data.total_score}}</td>
</tr>
</tbody>
{% endfor %}
</table>
If you pay attention, in the method that's executed in the './info' route, we have added a parameter which will be used to filter information from the database.
filter_by basically creates the WHERE clause in any SQL based database and the first() is a collector of the information, which will basically give the information corresponding to the first row, that is satisfying the filter.
Since two people can have the same name, we pass the {{data.id}} in the filter.
Using the information parameter passed in the render_template() of '/info' route you can make the info.html page.
So this should work. I have answered the question based on my understanding of the question.
Your question was unclear.
Let me know if you don't understand something or if I have misunderstood something.
First, retrieve all the data in the database table in, say, the info() view function:
#app.route('/info')
def info():
page = request.args.get('page', 1, type=int)
user_info = database.query.order_by(
database.timestamp.desc()).paginate(
page, app.config['POSTS_PER_PAGE'], False
)
next_url = url_for('info',
page=user_info.next_num) \
if user_info.has_next else None
prev_url = url_for('info',
page=user_info.prev_num) \
if user_info.has_prev else None
return render_template('info.html',
title='User Information',
next_url=next_url,
prev_url=prev_url,
user_info=user_info.items
)
In my example, I am querying the database in the order of the time a user was recorded in the database. For now you do not have that field, but I just wanted to point that out in case you want to use it. That would mean you add a new column timestamp = db.Column(db.DateTime, default=datetime.utcnow) to database.
Additionally, I have added pagination such that in the event your database has so many entries, you can choose to show a certain amount of data in per page, with the option to move to page 2, 3 ... Read more from the documentation.
With data now in user_info, you can use a for loop to display all user information.
<table class="css-serial">
<tbody>
<tr>
<th>Rank</th>
<th>ID</th>
<th>Name</th>
<th>Profile Summary</th>
<th>Personality Score</th>
<th>Skills Score</th>
<th>Experience Score</th>
<th>Total Score</th>
</tr>
{% for data in user_info %}
<tr>
<td></td>
<td>{{data.id}}</td>
<td><a href=info>{{ data.name }}</a></td>
<td>{{ data.text }}</td>
<td>{{ data.personality_score }}</td>
<td>{{data.skills_score}}</td>
<td>{{data.experience_score}}</td>
<td>{{data.total_score}}</td>
</tr>
{% endfor %}
</tbody>
</table>
I have data in the following (simplified) format:
MetricData(models.Model) with following fields: id, metric, date, facility, value
Now I want to create a table with the following format (execute the script to get the indented output table):
<table style="width:100%">
<tr>
<th>Date</th>
<th>Facility 1</th>
<th>Facility 2</th>
<th>Facility 3</th>
</tr>
<tr>
<td>03/2019</td>
<td>1.0</td>
<td>1.5</td>
<td>2.5</td>
</tr>
<tr>
<td>04/2019</td>
<td>1.5</td>
<td>1.5</td>
<td>2.0</td>
</tr>
</table>
As you can see, the number of facilities which is dynamic (new ones can be added to the database), are the column headers. For each facility there will be metric data in the database.
All examples from django-datatables-view I find are basically using models directly and one model entry is converted to one table row.
You can override the QuerySet for your model to get a list of headers:
class MetricDataQuerySet(models.QuerySet):
#property
def headers(self):
return [getattr(instance, self.model.header_column) for instance in self]
class MetricData(models.Model):
header_column = 'facility'
...
objects = MetricDataQuerySet.as_manager()
Notice I added the header_column, instead of hard coding facility in the QuerySet. This allows you to reuse the QuerySet for different models if you end up needing to.
Now, in your view:
def some_view(request):
...
context = {
'objects': MetricData.objects.all()
}
return render(request, 'some_template.html', context)
Finally, on some_template.html, you can do this:
<table>
<tr>
{% for header in objects.headers %}
<th>{{ header }}</th>
{% endfor %}
</tr>
{% for object in objects %}
<tr>
<td>row.date</td>
<td>row.metric</td>
<td>row.value</td>
</tr>
{% endfor %}
</table>
I want to display the content of the database from .db file on web framework using flask module. However, only the row title is able to be displayed on the web framework. The content of the database from the .db file couldn't load out on the web framework. Anyone can help me with this? Thanks.
This is my code:
from flask import Flask, render_template
import sqlite3
app = Flask(__name__)
def connect_db(db):
con = sqlite3.connect(db)
return con.cursor()
#app.route('/')
def index():
db ='mcu_aurix_git.db'
cur = connect_db(db)
cur.execute("SELECT * FROM mcu_aurix")
data = cur.fetchall()
return render_template('flask.html', rows=data)
if __name__ == "__main__":
app.run(debug=True)
flask.html:
<table class="table table-hover">
<thead>
<tr>
<th>project</th>
<th>branch</th>
<th>id</th>
<th>number</th>
<th>subject</th>
<th>owner_name</th>
<th>owner_email</th>
<th>owner_username</th>
<th>url</th>
<th>commitMessage</th>
<th>createdOn</th>
<th>lastUpdated</th>
<th>open</th>
<th>status</th>
<th>current_date</th>
</tr>
</thead>
<tbody>
{% for row in rows %}
<tr>
<td>{{row.project_name}}</td>
<td>{{row.branch_id}}</td>
<td>{{row.id_id}}</td>
<td>{{row.num_number}}</td>
<td>{{row.subject_name}}</td>
<td>{{row.owner_name}}</td>
<td>{{row.owner_email}}</td>
<td>{{row.owner_username}}</td>
<td>{{row.url_name}}</td>
<td>{{row.commitMessage_name}}</td>
<td>{{row.num_createdOn}}</td>
<td>{{row.num_lastUpdated}}</td>
<td>{{row.num_open}}</td>
<td>{{row.status_name}}</td>
<td>{{row.current_date}}</td>
</tr>
{% endfor %}
</tbody>
</table>
Is there anything missing in my code? Hopefully anyone can help me on this. Thanks in advance!
You are not passing rows variable to the html page.
return render_template('flask.html', data=data)
You are only passing data variable.
If you want to use rows inside your html page, you need to use
return render_template('flask.html', rows=data)
Also one more thing,
{{row.project_name}}
You cannot get the value of project_name like this, you need to use index value (col. no. starting from 0). Like,
{{row[0]}}
Instead of manually creating <td> for each col value, you can just use the below tbody code.
<tbody>
{% for row in rows %}
<tr>
{% for col in row %}
<td> {{ col }} </td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
Hope it helps!
In my basic web application, when click to "calculate" button there can be two options.
First, there is only one result so I directly show them to the users.
Secondly, there can be more than one result so I need to use table to show my results.
For the first option, I can show my result like below:
<p>Result {{result}}</p>
But I cannot figure out if my "result" parameter is array and how can I show all values of array in the table in my html file.
Any help is appreciated.
You can iterate over your iterable in your template:
Python script:
users = [{"name": "123", "hash": "qwe"},]
#app.route('/index/')
def index_page():
return render_template('index.html', users=users)
Template:
<table>
<thead>
<tr>
<th><span>Hash - Name</span></th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>
<span>{{user['hash']}} - {{user['name']}}</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
See here for more details about iterating over a loop in jinja2 templater.
You can send your result to render in python script:
#app.route('/')
def index():
return render_template('index.html', result='yes')
And in tempalte:
<p>Result {{ result }}</p>
In browser:
<p>Result yes</p>