Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I add multiple arguments to my custom template filter in a django template?

Here's my custom filter:

from django import template  register = template.Library()  @register.filter def replace(value, cherche, remplacement):     return value.replace(cherche, remplacement) 

and here are the ways I tried using it in my template file that resulted in an error:

{{ attr.name|replace:"_"," " }} {{ attr.name|replace:"_" " " }} {{ attr.name|replace:"_":" " }} {{ attr.name|replace:"cherche='_', remplacement=' '" }} 

I looked into django's docs and book but only found example using a single argument... is it even possible?

like image 796
bchhun Avatar asked Jan 07 '09 15:01

bchhun


People also ask

How do you pass variables from Django view to a template?

How do you pass a Python variable to a template? And this is rather simple, because Django has built-in template modules that makes a transfer easy. Basically you just take the variable from views.py and enclose it within curly braces {{ }} in the template file.


1 Answers

It is possible and fairly simple.

Django only allows one argument to your filter, but there's no reason you can't put all your arguments into a single string using a comma to separate them.

So for example, if you want a filter that checks if variable X is in the list [1,2,3,4] you will want a template filter that looks like this:

{% if X|is_in:"1,2,3,4" %} 

Now we can create your templatetag like this:

from django.template import Library  register = Library()  def is_in(var, args):     if args is None:         return False     arg_list = [arg.strip() for arg in args.split(',')]     return var in arg_list  register.filter(is_in) 

The line that creates arg_list is a generator expression that splits the args string on all the commas and calls .strip() to remove any leading and trailing spaces.

If, for example, the 3rd argument is an int then just do:

arg_list[2] = int(arg_list[2]) 

Or if all of them are ints do:

arg_list = [int(arg) for arg in args.split(',')] 

EDIT: now to specifically answer your question by using key,value pairs as parameters, you can use the same class Django uses to parse query strings out of URL's, which then also has the benefit of handling character encoding properly according to your settings.py.

So, as with query strings, each parameter is separated by '&':

{{ attr.name|replace:"cherche=_&remplacement= " }} 

Then your replace function will now look like this:

from django import template from django.http import QueryDict  register = template.Library()  @register.filter def replace(value, args):     qs = QueryDict(args)     if qs.has_key('cherche') and qs.has_key('remplacement'):         return value.replace(qs['cherche'], qs['remplacement'])     else:         return value 

You could speed this up some at the risk of doing some incorrect replacements:

qs = QueryDict(args) return value.replace(qs.get('cherche',''), qs.get('remplacement','')) 
like image 174
Van Gale Avatar answered Sep 30 '22 00:09

Van Gale