[Django]-Is there a django template filter to display percentages?

3👍

The newness of string.Formatter() means that Django is not likely to support it built-in. Either write or find a template tag or filter that implements it.

89👍

I was looking for almost the same question and found the widthratio template tag.
Instead of having the percentage already calculated like in your question, you can use this tag to calculate the percentage in the template from the original value and total value against which your percentage is calculated. It does the job if you only need an integer percentage without precision:

{% widthratio value total_value 100 %}

Ref: https://docs.djangoproject.com/en/dev/ref/templates/builtins/#widthratio

27👍

In case somebody is looking for the answser, this is how I solved the problem with a custom templatetag:

from django import template

register = template.Library()

@register.filter
def percentage(value):
    return format(value, "%")
👤jbochi

17👍

Here’s what I’m using (we only show decimals, not floats, by the way):

@register.filter
def as_percentage_of(part, whole):
    try:
        return "%d%%" % (float(part) / whole * 100)
    except (ValueError, ZeroDivisionError):
        return ""

Use it like this:

Monkeys constitute {{ monkeys|as_percentage_of:animals }} of all animals.

where if monkeys is 3 and animals is 6, you’ll get:

50%
👤tobych

9👍

This is how I solved the problem:

from django import template

register = template.Library()

def percentage(value):
    return '{0:.2%}'.format(value)

register.filter('percentage', percentage)

3👍

Better solution with internationalization works with python 2.5.

from django import template

register = template.Library()
from django.template.defaultfilters import floatformat

@register.filter
def percent(value):
  if value is None:
    return None
  return floatformat(value * 100.0, 2) + '%' 

0👍

The shortest way to have a number formated with percent, for example “65%” :

{{ number|stringformat:"d%%" }}
👤Cyril

0👍

Putting my 2 cents in as most of the previous answers are fine already, but I spent some time looking for a fully customisable and flexible solution and wanted to share my findings.

Fully customisable and flexible means writing a custom filter, so let’s do that. In your app’s root directory, create the "templatetags" package and the "templatetags/mytags.py" file, with the following content:

# mytags.py
from django import template
register = template.Library()

@register.filter(is_safe=True)
def format_percent(value: float, args: str=""):
    """
    Format a numeric value as percentage
    :param value: the numeric value
    :param args: a CSV string of arguments to the formatting operation
    :return: the formatted value
    """
    # splits the arguments string into a list of arguments
    arg_list = [arg.strip() for arg in args.split(',')] if args else []
    # sets the precision (number of decimal digits)
    precision = int(arg_list[0]) if len(arg_list) > 0 else 0
    # should the "%" symbol be included?
    include_symbol = bool(arg_list[1]) if len(arg_list) > 1 else True
    symbol = " %" if include_symbol else ""
    # builds and returns the formatted value
    return f"{value * 100.0:.{precision}f}{symbol}"

You can choose any name you like for your custom filters’ file, only be careful that the name you choose is the name you’ll use to load the tags later, so make sure you pick a name that won’t clash with custom tags and filters in another app.

Also note that "templatetags" is not a simple directory but a Python package, so make sure you also include the standard __init__.py into it.

Finally note that I had to revert to the "args" trick in my filter, because Django does not support custom filters with more than one argument.

Now you can use the new tag like in the following example:

# mytemplate.html
# note that the app that contains the custom tags must be in INSTALLED_APPS
# in order for the {% load %} tag to work
{% load mytags %}

<p>{{ 0.1234|format_percent}}</p>
<p>{{ 0.1234|format_percent:"1"}}</p>
<p>{{ 0.1234|format_percent:"2,False" }}</p>

which would render something like this:

12%
12.3%
12.34%

I believe this is quite a flexible solution as you can easily add more formatting parameters to the custom filter if you need those.

Leave a comment