Looks like a question that should be already covered, but after spending some time, I did not find how to check that a variable is numeric in Django template.
Something like
{% if my_var.isnumeric %}
# do something
{% endif %}
UPDATE
As I learnt from the below discussion, there seems to be no built-in tag to check this, and we end up having to create our own template tag.
Assuming that "numeric" means "contains only digits" (and no decimal point, no minus sign, etc.)
Custom filter is your best bet:
from django import template
register = template.Library()
#register.filter(is_safe=True)
def is_numberic(value):
return "{}".format(value).isdigit()
Docs about custom template filters: https://docs.djangoproject.com/en/1.9/howto/custom-template-tags/
Usage in templates:
{% load your_custom_lib %}
...
{% if something|is_numberic %}...
If you consider integers as numeric (positive and negative), then the function becomes:
try:
int("{}".format(value))
except ValueError:
return False
else:
return True
In case "numeric" means "integer or float", then use float instead of int. But note that this will also recognize -12E3 as numeric, because:
>>> -12E3
-12000.0
Does this work ?
{{ value|divisibleby:"1" }}
EDIT: Nope, raises an exception if a string is given.
Related
Is it possible to append 2 context variables together into a single context variable that is calculated at run-time?
For example: if I have {{contextA}} (which equals 1) and {{contextB}} (which equals 'building') and I wanted to add these together to get context {{1building}} How would I do this?
I have tried:
{{contextA + contextB}}
{{{{contextA}} + {{contextB}}}}
{{contextA |add: contextB}}
{{contextA contextB}}
I suppose this is not possible and this needs to be done in the view using python, but it would be ideal if I could just combine context variables in the template.
U can use {% with template tag as follows (docs here -> https://docs.djangoproject.com/en/3.0/ref/templates/builtins/#with)
{% with newvar=contextA|add:contextB %}
{{ newvar }}
{% endwith %}
newvar will have a new value if into a forloop where contextA or contextB change it's value.
As you want to show the value of a context variable with it's name equal to newvar value, the way to accomplish it is to create a custom template tag as follows:
#register.simple_tag(takes_context=True)
def dynvarvalue(context, dynvarname):
""" Returns the value of dynvarname into the context """
return context.get(dynvarname, None)
I did a small proof of concept:
{% with 1building='1 building value' contextA='1' contextB='building' %}
{% dynvarvalue contextA|add:contextB %}
{% endwith %}
Which produces the following output, which I think is what you are asking for:
1 building value
Hope this helps.
Note: take into account that if both variables can be transformed to an integer, they will not be concatenated and will be summed as docs says (https://docs.djangoproject.com/en/3.0/ref/templates/builtins/#add)
Note2: I think there are some security caveats to take into account doing this.
I want to use django built-in template tag forloop.counter0 in a math expression. This is what I came up with:
{% for category in categories %}
<li class="wow fadeInUp" data-wow-delay="{{ forloop.counter0 * 0.1 }}s">
//whatever
</li>
{% endfor %}
Which I learn is wrong cause of this error:
Could not parse the remainder: ' * 0.1' from 'forloop.counter0 * 0.1'
Is it anyway to solve this issue?
Isn't there anyway that I could use a built-in function in a math expression?
One can use widthratio tag to achieve this, also you can use custom templatetag, as stated in the comment by Mauricio, but in widthratio the final value should be a number and cannot be a float, so that may be problem.
So there is a third way to achieve this by using template-filters
So for multiplication you can put this in your templatetags
from django import template
register = template.Library()
#register.filter(is_safe=False)
def multiply(value, arg):
"""Multiply the arg to the value."""
try:
return float(value) * float(arg)
except (ValueError, TypeError):
try:
return value * arg
except Exception:
return ''
and use this in template like
{{ forloop.counter0|multiply:'0.1' }}
{{ '0.002'|multiply:'0.21' }} # Output : 0.00042
Here the value and the arg need not be int, it can be a float too, also no need of loading any tag for multiplication in templates.
I am pulling a name from a database which is stored as myname. How do I display this inside a Django template as Myname, with the first letter being in uppercase.
Using Django built-in template filter called title
{{ "myname"|title }}
I know it's a bit late, but you can use capfirst:
{{ "waiting for action"|capfirst }}
This will result into "Waiting for action"
This solution also works if you have multiple words (for example all caps):
{{ "ALL CAPS SENTENCE"|lower|capfirst }}
This will output "All caps sentence".
The title filter works fine, but if you have a many-words string like: "some random text", the result is going to be "Some Random Text". If what you really want is to uppercase only the first letter of the whole string, you should create your own custom filter.
You could create a filter like this (follow the instructions on how to create a custom template filter from this doc - it's quite simple):
# yourapp/templatetags/my_filters.py
from django import template
register = template.Library()
#register.filter()
def upfirstletter(value):
first = value[0] if len(value) > 0 else ''
remaining = value[1:] if len(value) > 1 else ''
return first.upper() + remaining
Then, you should load the my_filters file at your template, and use the filter defined there:
{% load my_filters %}
...
{{ myname|upfirstletter }}
It worked for me in template variable.
{{ user.username|title }}
If the user is "al hasib" then the it will return "Al Hasib"
or
{{ user.username|capfirst }}
If user is 'hasib' then the last one will return "Hasib"
Both look something like same but there's some differences.
use
{{"myname"|title}}
this will make the fist letter of each word capital
Just use {{myname | capfirst}}
In Django the template filter capfirst capatialize the first letter of a given string.
what does django do, when i do something like that in template
{{ object.parameter }}
I ask this because in case of arrayfields (postgresql array fields) it will print out either
{'value', 'value', 'value'}
(because thats how postgresql stores arrays in arrayfields)
or
['value','value','value']
if i use fields post_init method to convert postgresql array to python list.
Desired output would of course be value, value, value. I would rather not use some kind of filters for that, because then i would have to resort using IFs in templates or use some kind of template tag filter for every value i print out and that does not feel like a smart thing to do.
By the way, i know i can do something like that in template :
{% for choice in field.choices %}
{{ choice }}
{% if forloop.last %}
{% else %},
{% endif%}
{% endfor %}
and that gives me exactly what i want, but i thought there would be some other way doing it - with some modelfield method or something.
Alan
what does django do, when i do something like that in template
{{ object.parameter }}
See variables and lookups.
Desired output would of course be value, value, value. I would rather not use some kind of filters for that, because then i would have to resort using IFs in templates or use some kind of template tag filter for every value i print out and that does not feel like a smart thing to do.
You can make a really trivial filter:
#register.filter
def comma_join(values):
return u', '.join(values)
So simple:
{{ object.parameter|comma_join }}
Why would you want to avoid such a simple solution ?
and that gives me exactly what i want, but i thought there would be some other way doing it - with some modelfield method or something.
Of course you could also add such a method:
class YourModel(models.Model):
# ....
def comma_join_parameter(self):
return u', '.join(self.parameter)
And use it in your template as such:
{{ object.comma_join_parameter }}
I have this code situation
{% if 1|floatformat in '7,10' %}
yes
{% else %}
no
{% endif %}
the return result is always set to "yes", how to make the result return "no"
please help.
thanks
It's hard to make out from your example what exactly is happening here, because you're substituting dummy data for what's really coming out of the database.
As you've written it, the result will always be "yes" because the string '7,10' contains the string '1'.
It sounds like what you're trying to achieve is:
If this number is in this list, then yes, otherwise no.
So let's rewrite this template to be a little more real:
{% if mynumber in yeslist %} yes {% else %} no {% endif %}
This assumes that:
mynumber is a number
yeslist is a list of numbers
I'm not sure what you're using floatformat for in this case.
If the above assertions aren't true, and you have to use strings, then your work is much harder, and you should be processing yeslist server-side. For example, if yeslist is just a string like "7,10,123,93,9,19,83", then figuring out if the number 8 is in the list will be needlessly difficult in templates. Much easier to do it in your view:
def myview(request):
ctx = {}
# ... do some work ...
# yeslist now has a string like "7,10,123,93,9,19,83"
ctx['yeslist'] = yeslist.split(',')
# ... do more work, and render the response ...
Now, {% if '8' in yeslist %} will no longer return a false positive, because it's not doing a substring match, it's doing list membership.
1|floatformat returns 1 and the condition checks if 1 is in '7,10', since django considers '7,10' as a string it returns True. Try passing a list and it will return no