check variable is numerical django template - django

Hi I want to check if my variable is numeric in Django template
and I tried this code
{% if isnumeric(item) %}
<h1>{{item}}</h1>
{% endif %}
but this throws me this error
Could not parse the remainder: '(item)' from 'isnumeric(item)'
I tried to find a builtin template tag or filter in this page
https://docs.djangoproject.com/en/3.1/ref/templates/builtins/ of Django document
and I searched for this question in StackOverflow too
but I did not found anything related

I don't believe there's a built in template function to check for that. One way to do it is to write your own:
https://docs.djangoproject.com/en/3.1/howto/custom-template-tags/
The code would look something like:
my_filters.py
from django import template
register = template.Library()
#register.filter()
def is_numberic(value):
return value.isdigit()
And in the html:
{% load my_filters %}
{% if item|is_numeric %}
...

isnumeric() python fuction doesn't take any parameters
Make a fuction in your model:
def isnumeric(self):
item = self.item
if item.isnumeric() is True:
return True
else:
return False
then in your template:
{% if item.isnumeric %}
<h1>{{item}}</h1>
{% endif %}
With this, you can use the isnumeric() function in your template. You can add an else statement too.
Take a look to isnumeric() function

Related

if statement to determine which route is used in jinja template, flask

I have two views which uses one template.
#users.route("/one")
#login_required
def one(username):
return render_template('follower.html')
and
#users.route("/two")
#login_required
def two(username):
return render_template('follower.html')
in the jinja template ( follower.html ), I am trying to execute a program if route one is used like this:
{% if url_for('users.one') %}
execute program
{% endif %}
but it seems I am doing it wrongly. Please what is the correct way of determine which route is used?
You can simply, in your template file, write a condition to check if request.endpoint equals the function name for the desired route, which in this case would be one, as seen in this example:
{% if request.endpoint == 'one' %}
execute program
{% endif %}
In this way, you will not make any changes to your route functions.
You cannot have two functions with the same name - they are both named two.
One simple way to accomplish this is to pass in a flag. E.g.,
#users.route("/one")
#login_required
def one(username):
return render_template('follower.html', one=True)
then check for it in the template
{% if one %}
execute program
{% endif %}
from two() you'd padd one=False.

Custom assignment tag received too many positional arguments

Im using django 1.7.8 and checking doc : https://docs.djangoproject.com/en/1.7/howto/custom-template-tags/#assignment-tags. I have written a assignment tag to check permissions. Under /templatetags/folder_perms.py
from django import template
register = template.Library()
#register.assignment_tag(takes_context=True)
def get_folder_permission(context, folder):
request = context['request']
return folder.has_read_permission(request)
I use it in my template like so:
...
{% load folder_perms_tags %}
...
{% get_folder_permission 'object.folder' as curr_perm %}
{{ curr_perm }}
...
When I render my template I get an error
'get_folder_permission' received too many positional arguments
Wow im so dumb, was loading the wrong template tags
just had to change
{% load folder_perms_tags %}
to
{% load folder_perms %}

How to store the result of a templatetag using Django templates?

Working with Django 1.5.5 I need to call a custom templatetag and somehow store the result in a variable, to check if it contains a non empty empty string. I need something that should look like:
{% load smart_html %}
{% render_html widget.content as widget_content %}
{% if widget_content %}
Do stuff here...
{% endif %}
This is inspired on the {% url %} built-in templatetag that allows calling it storing the result in a variable using the syntax:
{% url 'named_url' as my_named_url %}
My templatetag looks like:
#register.simple_tag(takes_context=True)
def render_html(context, html):
"""Allows executing 'Django code' within the HTML"""
return Template(html).render(context)
I also thought about adding the returned value from the custom templatetag to the context. What do you think about this? Would this be dangerous? This would look like:
#register.simple_tag(takes_context=True)
def render_html(context, html, var_name=None):
"""Allows executing 'Django code' within the HTML"""
html = Template(html).render(context)
if var_name:
context[var_name] = html
html = ''
return html
If the tag is something you control, then perhaps consider using an assignment tag. If the tag isn't something you control, then you might have to wrap it with an assignment tag of your own.
#register.assignment_tag(takes_context=True)
def render_html(context, content):
return Template(content).render(context)
But I don't know what you are trying to achieve? Isn't it better to do this kind of stuff in your view function and based on the result call different templates with TemplateResponse?

Django template - dynamic variable name

Good Afternoon,
How can I use a variable variable name in Django templates?
I have a custom auth system using context, has_perm checks to see if the user has access to the specified section.
deptauth is a variable with a restriction group name i.e SectionAdmin. I think has.perm is actually checking for 'deptauth' instead of the variable value SectionAdmin as I would like.
{%if has_perm.deptauth %}
How can I do that? has_perm.{{depauth}} or something along those lines?
EDIT - Updated code
{% with arg_value="authval" %}
{% lookup has_perm "admintest" %}
{% endwith %}
{%if has_perm.authval %}
window.location = './portal/tickets/admin/add/{{dept}}/'+val;
{% else %}
window.location = './portal/tickets/add/{{dept}}/'+val;
{%endif%}
has_perm isn't an object.. it's in my context processor (permchecker):
class permchecker(object):
def __init__(self, request):
self.request = request
pass
def __getitem__(self, perm_name):
return check_perm(self.request, perm_name)
You're best off writing your own custom template tag for that. It's not difficult to do, and normal for this kind of situation.
I have not tested this, but something along these lines should work. Remember to handle errors properly!
def lookup(object, property):
return getattr(object, property)()
register.simple_tag(lookup)
If you're trying to get a property rather than execute a method, remove those ().
and use it:
{% lookup has_perm "depauth" %}
Note that has_perm is a variable, and "depauth" is a string value. this will pass the string for lookup, i.e. get has_perm.depauth.
You can call it with a variable:
{% with arg_value="depauth_other_value" %}
{% lookup has_perm arg_value %}
{% endwith %}
which means that the value of the variable will be used to look it up, i.e. has_perm.depauth_other_value'.
You can try like this,
{{ dict|key:key_name }}
Filter:
def key(d, key_name):
return d[key_name]
key = register.filter('key', key)
More information, django ticket

if..else custom template tag

I'm implementing a custom permissions application in my Django project, and I'm lost as to how to implement a custom template tag that checks a logged in user's permissions for a specific object instance and shows a piece of HTML based on the outcome of the check.
What I have now is (pseudocode):
{% check_permission request.user "can_edit" on article %}
<form>...</form>
{% endcheck %}
('check_permission' is my custom template tag).
The templatetag takes in the user, the permission and the object instance and returns the enclosed HTML (the form). This currently works fine.
What I would like to do however, is something like:
{% if check_permission request.user "can_edit" on article %}
<form>...</form>
{% else %}
{{ article }}
{% endif %}
I've read about the assignment tag, but my fear is that I would pollute the context variable space with this (meaning I might overwrite previous permission context variables). In other words, as the context variables are being defined on different levels (the view, middleware in my case, and now this assignment template tag), I'm worried about maintainability.
You can use template filters inside if statements. So you could rewrite your tag as a filter:
{% if request.user|check_can_edit:article %}
Note that it's tricky to pass multiple arguments of different types to a filter, so you'll probably want to use one filter per permission, above I've used check_can_edit.
You can definitely do that if you're willing to write some more lines of python code to improve your template readability! :)
You need to parse the tag content yourself, even the parameters it takes and then resolve them, if you want to use variables on them.
The tag implemented below can be used like this:
{% load mytag %}
{% mytag True %}Hi{% else %}Hey{% endmytag %} Bro
Or with a variable:
{% mytag myobject.myflag %}Hi{% else %}Hey{% endmytag %} Bro
So, here's the way I did it:
from django.template import Library, Node, TemplateSyntaxError
register = Library()
#register.tag
def mytag(parser, token):
# Separating the tag name from the "test" parameter.
try:
tag, test = token.contents.split()
except (ValueError, TypeError):
raise TemplateSyntaxError(
"'%s' tag takes two parameters" % tag)
default_states = ['mytag', 'else']
end_tag = 'endmytag'
# Place to store the states and their values
states = {}
# Let's iterate over our context and find our tokens
while token.contents != end_tag:
current = token.contents
states[current.split()[0]] = parser.parse(default_states + [end_tag])
token = parser.next_token()
test_var = parser.compile_filter(test)
return MyNode(states, test_var)
class MyNode(Node):
def __init__(self, states, test_var):
self.states = states
self.test_var = test_var
def render(self, context):
# Resolving variables passed by the user
test_var = self.test_name.resolve(context, True)
# Rendering the right state. You can add a function call, use a
# library or whatever here to decide if the value is true or false.
is_true = bool(test_var)
return self.states[is_true and 'myvar' or 'else'].render(context)
And that's it. HTH.
In Django 2 the assignment tag was replaced by simple_tag() but you could store the custom tag result as a template variable:
# I'm assuming that check_permission receives user and article,
# checks if the user can edit the article and return True or False
{% check_permission user article as permission_cleared %}
{% if permission_cleared %}
<form>...</form>
{% else %}
{{ article }}
{% endif %}
Check the current doc about custom template tags: https://docs.djangoproject.com/en/2.1/howto/custom-template-tags/#simple-tags
inside my_tags.py
from django import template
register = template.Library()
#register.simple_tag(takes_context=True)
def make_my_variable_true(context):
context['my_variable'] = True
return '' # without this you'll get a "None" in your html
inside my_template.html
{% load my_tags %}
{% make_my_variable_true %}
{% if my_variable %}foo{% endif %}
In this case best solution is to use custom filter. If you don't want write long code for custom tag. Also if you don't want to copy/paste others code.
Here is an example
Inside templatetag
register = template.Library()
def exam_available(user, skill):
skill = get_object_or_404(Skill, id=skill)
return skill.exam_available(user)
register.filter('exam_available', exam_available)
Inside template
{{ request.user|exam:skill.id }}
or
{% if request.user|exam:skill.id %}
Since one of the main common of it is to use request.user or any specific object(id) inside model's custom method, so filtering that individual object or user is the easiest way to make it done. :)