Filter 2D list with template tag in Django

Brandon Chetty

I'm trying to write a template tag that will filter a 2D list.

This is my template tag:

from django import template

register = template.Library()

@register.filter
def index_two(seq, position1, position2):
    return seq[position1][position2]

This is my list that I'm passing to my template:

summary = [[50, 0, 0], [50, 100, 100]]

I'm trying to reference the first element of the first list in summary, like so:

{{summary|index_two:0 0}}

However, I received a template syntax error: index_two requires 3 arguments, 2 provided.

I've tried to adjust my template tag to the answer here, but I can't get it to work for me.

Any suggestions?

Thanks

Willem Van Onsem

A Django template filter takes at most two parameters (the one that is passed with the "pipe" (|) character, and an optional extra one, like is specified in the documentation [Django-doc]:

Custom filters are just Python functions that take one or two arguments:

  1. The value of the variable (input) – not necessarily a string.
  2. The value of the argument – this can have a default value, or be left out altogether

But we can make the component more reusable, and thus obtain an single element each time, like:

from django import template

register = template.Library()

@register.filter
def index(seq, position):
    return seq[position]

Then we can write it like:

{{ summary|index:0|index:0 }}

So now we can use index to obtain an element of a list, and by chaining, we can dive deeper into the list. We thus make the function more reusable.

This technique is somewhat related to currying in functional programming where functions always take exactly one parameter.

Alternative, you can use some sort of format that can be decoded, like for example a string containing comma-separated values:

from django import template

register = template.Library()

@register.filter
def index_two(seq, positions):
    p1, p2 = map(int, positions.split(','))
    return seq[p1][p2]

and then use it like:

{{ summary|index_two:'0,0' }}

But personally I find this less elegant, and will probably cause more trouble, since it requires a well defined format, and it is always possible that it fails for some corner cases.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related