I am using Flask but this probably applies to a lot of similar frameworks.
I construct a pandas Dataframe, e.g.
#app.route('/analysis/<filename>')
def analysis(filename):
x = pd.DataFrame(np.random.randn(20, 5))
return render_template("analysis.html", name=filename, data=x)
The template analysis.html looks like
{% extends "base.html" %}
{% block content %}
<h1>{{name}}</h1>
{{data}}
{% endblock %}
This works but the output looks horrible. It doesn't use linebreaks etc.
I have played with data.to_html() and data.to_string()
What's the easiest way to display a frame?
The following should work:
#app.route('/analysis/<filename>')
def analysis(filename):
x = pd.DataFrame(np.random.randn(20, 5))
return render_template("analysis.html", name=filename, data=x.to_html())
# ^^^^^^^^^
Check the documentation for additional options like CSS styling.
Additionally, you need to adjust your template like so:
{% extends "base.html" %}
{% block content %}
<h1>{{name}}</h1>
{{data | safe}}
{% endblock %}
in order to tell Jinja you're passing in markup. Thanks to #SeanVieira for the tip.
Ok, I have managed to get some very nice results by now combining the hints I got here. In the actual Python viewer I use
#app.route('/analysis/<filename>')
def analysis(filename):
x = pd.DataFrame(np.random.randn(20, 5))
return render_template("analysis.html", name=filename, data=x)
e.g. I send the complete dataframe to the html template. My html template is based on bootstrap. Hence I can simply write
{% extends "base.html" %}
{% block content %}
<h1>{{name}}</h1>
{{ data.to_html(classes="table table-striped") | safe}}
{% endblock %}
There are numerous other options with bootstrap, check out here:
http://getbootstrap.com/css/#tables
Base.html is essentially copied from here
http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xii-facelift
The next question is obviously how to plot such a frame. Anyone any experience with Bokeh?
Thank you both to Matt and Sean.
thomas
Iterating over the rows of a df
If you need to have the df in a format that can iterate over the rows in your html, then use to_dict(orient='records'), which produces a dict in a format:
‘records’ : list like [{column -> value}, … , {column -> value}]
That way you can use your own way of displaying the data in your html.
The sample code would now look like this:
Python code using flask
#app.route('/analysis/<filename>')
def analysis(filename):
x = pd.DataFrame(np.random.randn(20, 5))
return render_template("analysis.html", name=filename, data=x.to_dict(orient='records'))
HTML code with jinja
{% extends "base.html" %}
{% block content %}
<table class="table">
<thead>
<tr>
<th scope="col">Column name 1</th>
<th scope="col">Column name 2</th>
<th scope="col">Column name 3</th>
</tr>
</thead>
<tbody>
{% for row in data %}
<tr>
<td>{{row['Column name 1']}}</td>
<td>{{row['Column name 2']}}</td>
<td>{{row['Column name 2']}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
You can use enaml-web to display and interact with pandas dataframes.
A few examples:
With filtering - https://github.com/frmdstryr/smd-search
Simple viewer - https://github.com/codelv/enaml-web/tree/master/examples/dataframe_viewer
Note: Interaction (sorting, filtering, etc...) requires a server with websocket support.
Related
Consider the below code:
<table id='table1'>
{% if model_name == 'TransactionsTable' %}
{% block transactions_create %}
{% include "snippets/transactions_create_and_update.html" with form=form %}
{% endblock transactions_create %}
{% endif %}
</table>
I have another <table>, 'table2', within transactions_create_and_update.html.
<table id=table2>abc</table>
Table2 was appearing outside of it's parent element. See image below - table2 should be inside of table1
So after some testing I tried closing table1 early (first line):
<table id='table1'></table>
{% if model_name == 'TransactionsTable' %}
{% block transactions_create %}
{% include "snippets/transactions_create_and_update.html" with form=form %}
{% endblock transactions_create %}
{% endif %}
Then it looks like this
I don't really understand what is going on in either scenario.
From the docs - think this is part of the answer but I don't know what to do with it:
The include tag should be considered as an implementation of “render
this subtemplate and include the HTML”, not as “parse this subtemplate
and include its contents as if it were part of the parent”. This means
that there is no shared state between included templates – each
include is a completely independent rendering process.
Blocks are evaluated before they are included. This means that a
template that includes blocks from another will contain blocks that
have already been evaluated and rendered - not blocks that can be
overridden by, for example, an extending template.
I had too many 'includes'. It turned out that one-level deeper I had a element that wasn't closed properly.
Is it possible to switch off Description column in Django Rest Framework Documentation? As you can see on the screenshot below there is a column Description. It is obvious what username and password mean, so I don't need to add more information, however empty cells don't look well. I would like to switch off it only for this method, because for instance in others I would like to have descriptions. Any ideas how can I do this?
There is no easy way to do this at the moment, since that 'Description' column is set at template level. See this template.
To be able to do this in a nicer way you need to customize rest_framework/docs/link.html, maybe have a template tag to check for a custom flag in here:
{% elif link.fields|with_location:'form' %}
<h4>Request Body</h4>
<p>The request body should be a <code>"{{ link.encoding }}"</code> encoded object, containing the following items.</p>
<table class="parameters table table-bordered table-striped">
<thead>
<tr><th>Parameter</th><th>Description</th></tr>
</thead>
<tbody>
{% for field in link.fields|with_location:'form' %}
<tr><td class="parameter-name"><code>{{ field.name }}</code>{% if field.required %} <span class="label label-warning">required</span>{% endif %}</td><td>{% if field.schema.description %}{{ field.schema.description }}{% endif %}</td></tr>
{% endfor %}
</tbody>
</table>
{% endif %}
But I think this is too much to consider just to have that column removed.
I have a table in SQLite3 and I need to take nearly all the columns in the table and output them to a web page. For other pages I've used flask, but that has always been a case of passing 3 or 4 single value variables into the template.
I'm guessing it's something like passing either the cursor or, more likely, the rows from the cursor.fetchall() call into the template then a for row in rows loop in the template?
It should be:
<table>
{% for item in items %}
<tr>
<td>{{column1}}</td>
<td>{{column2}}</td>
<td>{{column3}}</td>
<td>{{column4}}</td>
</tr>
{% endfor %}
</table>
You need to follow the below:
[HTML]:
<table>
{% for item in items %}
<tr>
<td>{{item[0]}}</td>
<td>{{item[1]}}</td>
<td>{{item[2]}}</td>
<td>{{item[3]}}</td>
</td>
{% endfor %}
[python code]:
cursor = db.execute('SELECT column1,column2,column3,column4 FROM tablename')
items = cursor.fetchall()
return render_template('print_items.html', items=items)
Pass your data as some sort of collection, whether that's something like a dictionary in the official tutorial, or something simpler, like a tuple or list.
Yes, in your template, you'll use a {% for item in collection %} -> {% endfor %} loop to render out all of the data from your database.
Example Python method:
#app.route('/print_items')
def print_items():
cursor = db.execute('SELECT column1,column2,column3,column4 FROM tablename')
return render_template('print_items.html', items=cursor.fetchall())
Example template section:
<table>
{% for item in items %}
<tr>
<td>column1</td>
<td>column2</td>
<td>column3</td>
<td>column4</td>
</td>
{% endfor %}
I'm developing a Django-based site for fun, and wondered if anyone knows how to solve this problem. I want to display images in a table, like a gallery, inside a template. Does anyone know how to do this? I've tried a multidimensional list, but I am getting nowhere.
I believe question is more CSS related than Django.
Are all your images the same size? If yes, just float all of them and let the bounding div break the images. Your template would looks like something like this (ignore the inline CSS!):
<div style="width:400px">
{% for image in image_list%}
<div style="float:left; width:100px; height:100px;">
{{ image.whatever }}
</div>
{% endfor%}
</div>
This would give you a "table" with 4 columns.
If your images have different widths and heights, I would go with something like display:inline-block, this article explains how it works:
http://robertnyman.com/2010/02/24/css-display-inline-block-why-it-rocks-and-why-it-sucks/
Edit If all you want is to convert a list into a table, I guess you can use this template:
{% for image in image_list %}
{% if forloop.first %}
<tr>
{% endif %}
<td>{{ forloop.counter }} - {{ image }}</td>
{% if forloop.last %}
</tr>
{% else %}
{% if forloop.counter|divisibleby:"4" %}
</tr><tr>
{% endif %}
{% endif %}
{% endfor %}
But this code is not tested! I just wrote it :)
Why don't you use a dictionary? Then you could represent points (0,0), (1,1), (0,1) etc with something like this,
mydict = {0: [0, 1, 2],
1: [0, 1, 2],
2: [0, 1, 2]}
where the elements of the list are your image names.
{0: ["image1.jpg", "image2.jpg", "image3.jpg"] .. }
In this case, mydict[0][0] refers to the first element of the first row, and so on.
--
To access a dict in the template (Django Doc), you could use something like,
# (key would be 0, value would be a list [0,1,2,3..]
{% for key, value in mydict.items %}
{% for img in value %}
<img src="{{img}}">
{% endfor %}
{% endfor %}
Do you really need to use table to align your images the way you need? If you need to get something like this http://blog.mozilla.com/webdev/files/2009/02/gallery-view.jpg, please take a look at inline-block CSS property. It is supported by all major browsers including IE6+ (with a little fix).
http://blog.mozilla.com/webdev/2009/02/20/cross-browser-inline-block/
Here's a much much simpler way that what others have answered:
The goal is to create a new row after each 4th image displayed. A 1 dimensional list is all you need.
One option would be to close the after each 4th . You can use the forloop.counter or you can use {% cycle '' '' '' '' %} after you create each tag. Note: I'm speculating a bit about your HTML structure. {% cycle '' '' '' '' %} might do just as fine.
Here is what cycle does: http://docs.djangoproject.com/en/dev/ref/templates/builtins/#cycle
If you're using s floated to the left, use the same cycle but add a line break after each 4th .
I have created a templatetag that loads a yaml document into a python list. In my template I have {% get_content_set %}, this dumps the raw list data. What I want to be able to do is something like
{% for items in get_content_list %}
<h2>{{items.title}}</h2>
{% endfor %}`
If the list is in a python variable X, then add it to the template context context['X'] = X and then you can do
{% for items in X %}
{{ items.title }}
{% endfor %}
A template tag is designed to render output, so won't provide an iterable list for you to use. But you don't need that as the normal context + for loop are fine.
Since writing complex templatetags is not an easy task (well documented though) i would take {% with %} tag source and adapt it for my needs, so it looks like
{% get_content_list as content %
{% for items in content %}
<h2>{{items.title}}</h2>
{% endfor %}`