I am trying to update variables inside of my index.html file. I am going to be running a thread with a loop in python but I want a way to update my jinja2 table listed below to update every x seconds just like if you were using php and ajax.
Here is my Jinja2 Code:
<table border=1 id="allTable" class="display">
<tbody id="eliteTable">
<tr><td colspan=9 class=queueheader>Elite (Current SLA: {{ eliteSLA | safe}}%)</td></tr>
<tr><th>Skill</th><th>SLA</th><th>Calls Waiting</th><th>Hold Time</th><th>Staffed</th><th>Avail</th><th>ACW</th><th>Aux</th><th>ACD Calls</th></tr>
{% for row in eliteList %}
{% if row[2]|int > 30 %}
<tr class=longwait>
{% elif row[2]|int > 0 %}
<tr class=waiting>
{% else %}
<tr>
{% endif %}
{% for i in row %}
<td> {{ i | safe }} </td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
You'll need some javascript in there.
Either ajax requests, or websockets, though ajax might be simpler.
Simply use javascript setInterval() with an ajax request.
I'd recommend using a library, maybe jquery as it is very simple.
$.get( "/auto_refresh", function( data ) {
alert( "Data Loaded: " + data );
});
Note that jinja2 is just for the templating, meaning that at some point the jinja templates get translated into html/css.
So you can play with ajax like you did when you were using PHP.
Jinja variables are generated at template render-time. There's no way to programmatically update them without using javascript of some sort.
From the docs (emphasis mine):
A [Jinja] template contains variables and/or expressions, which get replaced with values when a template is rendered; and tags, which control the logic of the template. The template syntax is heavily inspired by Django and Python.
Related
i have some situation where i got python dict as data which i want to check if any( any(dict.values) ) value exist or not.. but not sure how to use any() or all() function in django templates.
is there any built in filter ??
{% if search_result.result.show_more.values %}
<tr class="header">
<th colspan="4">{% trans 'Charges Info' %}</th>
</tr>
{% endif %}
if any value exist in showmore dict the i want to display header.
You could do this with custom template tags/filters, something like;
Django Template:
{% if values|python_all %}
{% if values|python_any %}
Template Tag:
from django import template
register = template.Library()
#register.filter(name='python_all')
def python_all(values):
return all(values)
#register.filter(name='python_any')
def python_any(values):
return any(values)
I'm building an admin for Flask and SQLAlchemy, and I want to pass the HTML for the different inputs to my view using render_template. The templating framework seems to escape the HTML automatically, so all <"'> characters are converted to HTML entities. How can I disable that so that the HTML renders correctly?
To turn off autoescaping when rendering a value, use the |safe filter.
{{ something|safe }}
Only do this on data you trust, since rendering untrusted data without escaping is a cross-site scripting vulnerability.
MarkupSafe provides Jinja's autoescaping behavior. You can import Markup and use it to declare a value HTML safe from the code:
from markupsafe import Markup
value = Markup('<strong>The HTML String</strong>')
Pass that to the templates and you don't have to use the |safe filter on it.
From the Jinja docs section HTML Escaping:
When automatic escaping is enabled everything is escaped by default
except for values explicitly marked as safe. Those can either be
marked by the application or in the template by using the |safe
filter.
Example:
<div class="info">
{{data.email_content|safe}}
</div>
When you have a lot of variables that don't need escaping, you can use an autoescape override block:
{% autoescape false %}
{{ something }}
{{ something_else }}
<b>{{ something_important }}</b>
{% endautoescape %}
For handling line-breaks specifically, I tried a number of options before finally settling for this:
{% set list1 = data.split('\n') %}
{% for item in list1 %}
{{ item }}
{% if not loop.last %}
<br/>
{% endif %}
{% endfor %}
The nice thing about this approach is that it's compatible with the auto-escaping, leaving everything nice and safe. It can also be combined with filters, like urlize.
Of course it's similar to Helge's answer, but doesn't need a macro (relying instead on Jinja's built-in split function) and also doesn't add an unnecesssary <br/> after the last item.
Some people seem to turn autoescape off which carries security risks to manipulate the string display.
If you only want to insert some linebreaks into a string and convert the linebreaks into <br />, then you could take a jinja macro like:
{% macro linebreaks_for_string( the_string ) -%}
{% if the_string %}
{% for line in the_string.split('\n') %}
<br />
{{ line }}
{% endfor %}
{% else %}
{{ the_string }}
{% endif %}
{%- endmacro %}
and in your template just call this with
{{ linebreaks_for_string( my_string_in_a_variable ) }}
Use the safe filter in your template, and then sanitize the HTML with the bleach library in your view. Using bleach, you can whitelist the HTML tags that you need to use.
This is the safest, as far as I know. I tried both the safe filter and the Markup class, and both ways allowed me to execute unwanted JavaScript. Not very safe!
I'm building an admin for Flask and SQLAlchemy, and I want to pass the HTML for the different inputs to my view using render_template. The templating framework seems to escape the HTML automatically, so all <"'> characters are converted to HTML entities. How can I disable that so that the HTML renders correctly?
To turn off autoescaping when rendering a value, use the |safe filter.
{{ something|safe }}
Only do this on data you trust, since rendering untrusted data without escaping is a cross-site scripting vulnerability.
MarkupSafe provides Jinja's autoescaping behavior. You can import Markup and use it to declare a value HTML safe from the code:
from markupsafe import Markup
value = Markup('<strong>The HTML String</strong>')
Pass that to the templates and you don't have to use the |safe filter on it.
From the Jinja docs section HTML Escaping:
When automatic escaping is enabled everything is escaped by default
except for values explicitly marked as safe. Those can either be
marked by the application or in the template by using the |safe
filter.
Example:
<div class="info">
{{data.email_content|safe}}
</div>
When you have a lot of variables that don't need escaping, you can use an autoescape override block:
{% autoescape false %}
{{ something }}
{{ something_else }}
<b>{{ something_important }}</b>
{% endautoescape %}
For handling line-breaks specifically, I tried a number of options before finally settling for this:
{% set list1 = data.split('\n') %}
{% for item in list1 %}
{{ item }}
{% if not loop.last %}
<br/>
{% endif %}
{% endfor %}
The nice thing about this approach is that it's compatible with the auto-escaping, leaving everything nice and safe. It can also be combined with filters, like urlize.
Of course it's similar to Helge's answer, but doesn't need a macro (relying instead on Jinja's built-in split function) and also doesn't add an unnecesssary <br/> after the last item.
Some people seem to turn autoescape off which carries security risks to manipulate the string display.
If you only want to insert some linebreaks into a string and convert the linebreaks into <br />, then you could take a jinja macro like:
{% macro linebreaks_for_string( the_string ) -%}
{% if the_string %}
{% for line in the_string.split('\n') %}
<br />
{{ line }}
{% endfor %}
{% else %}
{{ the_string }}
{% endif %}
{%- endmacro %}
and in your template just call this with
{{ linebreaks_for_string( my_string_in_a_variable ) }}
Use the safe filter in your template, and then sanitize the HTML with the bleach library in your view. Using bleach, you can whitelist the HTML tags that you need to use.
This is the safest, as far as I know. I tried both the safe filter and the Markup class, and both ways allowed me to execute unwanted JavaScript. Not very safe!
I am trying to do multi-column sorting in django-tables2.
I can add ?sort=date&sort=job_number
to the end of my url and it will sort by date, then job number.
But when a user clicks a column heading, it will replace the current sort querystring with the new one! Is there a way to more elegantly expose multi-column sort to the end users?
I am using the 'querystring' tag from django-tables2, but as stated above, it rewrites the value instead of appending it.
Okay, I have worked out a solution that works, but it isn't quite perfect, so if anyone wants to propose something better, I'm all ears!
First, I created a new templatetag (see https://docs.djangoproject.com/en/1.8/howto/custom-template-tags/ for details about where to put a custom templatetag)
from django import template
from django_tables2.templatetags.django_tables2 import querystring
register = template.Library()
#register.inclusion_tag('django_tables2/header.html', takes_context=True)
def render_header(context):
for column in context['table'].columns:
column.sort_existing = False
if 'sort' in context['request'].GET:
if column.name in context['request'].GET['sort']:
column.sort_existing = True
return context
Then, I created a custom template called django_tables2/header.html for that tag to use:
{% load querystring from django_tables2 %}
<thead>
<tr>
{% for column in table.columns %}
{% if column.orderable %}
{% if column.sort_existing %}
<th {{ column.attrs.th.as_html }}><a href='{% querystring table.prefixed_order_by_field=column.order_by_alias.next %}'>{{ column.header }}</a></th>
{% else %}
<th {{ column.attrs.th.as_html }}><a href='{% querystring %}&{{ table.prefixed_order_by_field }}={{ column.order_by_alias }}'>{{ column.header }}</a></th>
{% endif %}
{% else %}
<th {{ column.attrs.th.as_html }}>{{ column.header }}</th>
{% endif %}
{% endfor %}
</tr>
</thead>
And Finally, I altered my django_tables2/table.html template to use my custom templatetag to render the table header, replace the table.thead block with:
{% block table.thead %}
{% render_header %}
{% endblock table.thead %}
And that should do the trick! Clicking on multiple column headers will sort them in the order clicked, clicking on a the same one twice will clear previous selections (and reverse the order). It isn't perfect. Perhaps I'll improve upon it later, but it works for my immediate use case.
Perhaps I will reach out to the django_tables2 project to see if they are interested in including my custom template tag into the main project :)
EDIT: I should note, this requires 'django.core.context_processors.request' or equivalent in your context processors in your settings.
EDIT: Fixed table.html to correct code. Also, see https://github.com/bradleyayers/django-tables2/issues/223 to track this issue.
It looks like this is not an option for django-tables2 at the moment, though it is noted as an issue on the git page. I would also like to see this as on option for this package as well.
Looking through the source code briefly in the table.html template the href for the column header is produced by the following code: {% querystring table.prefixed_order_by_field=column.order_by_alias.next %}. Digging a little deeper it appears that there is an OrderByTuple object, that seems to want to perform this function, but never gets passed to the rendering. I haven't dug down enough to figure out why this OrderByTuple is not passed to the href, but may have something to do with the fact the the OrderBy called from the template referenced above is linked to the column and not the table. Sorry I couldn't acutually come up with a solution, but hope this helps a little.
I'm looking for short conditional statement in python/django templates, so I could write less and reuse more. Something like (tkey in disabled_rows) ? "disabled-row" : "".
Here's what I'm doing:
{% if tkey in disabled_rows %}
<tr class="disabled-row">
{% else %}
<tr>
{% endif %}
I also tried a custom template tag without success:
{{ (tkey in disabled_rows)|xif:'true,false' }}
xif implementation:
def xif(cond, args):
if cond:
return args.split(',')[0]
else:
return args.split(',')[1]
Extra points if you can explain why this is not implemented natively in python.
For the example you gave, this solution is short and simple:
<tr {% if tkey in disabled_rows %} class="disabled-row"{% endif %}>
Perhaps there is something else you're trying to achieve that would be better elucidated with a different example?