Comment append plusieurs arguments à mon filtre de modèle personnalisé dans un modèle Django?

Voici mon filtre personnalisé:

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

et voici comment j’ai essayé de l’utiliser dans mon fichier modèle qui a entraîné une erreur:

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

J’ai regardé dans les docs et les livres de django, mais je n’ai trouvé que des exemples en utilisant un seul argument … est-ce possible?

C’est possible et assez simple.

Django n’autorise qu’un seul argument pour votre filtre, mais il n’y a aucune raison pour que vous ne puissiez pas mettre tous vos arguments dans une seule chaîne en utilisant une virgule pour les séparer.

Par exemple, si vous voulez un filtre qui vérifie si la variable X est dans la liste [1,2,3,4], vous voudrez un filtre de modèle qui ressemble à ceci:

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

Maintenant, nous pouvons créer votre templatetag comme ceci:

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

La ligne qui crée arg_list est une expression de générateur qui divise la chaîne args sur toutes les virgules et appelle .ssortingp () pour supprimer tous les espaces de début et de fin.

Si, par exemple, le 3ème argument est un int alors faites simplement:

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

Ou si tous sont ints faire:

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

EDIT: maintenant, pour répondre spécifiquement à votre question en utilisant des paires clé-valeur comme parameters, vous pouvez utiliser la même classe que Django pour parsingr les chaînes de requête à partir des URL, ce qui a l’avantage de gérer correctement l’encodage des caractères. .

Ainsi, comme pour les chaînes de requête, chaque paramètre est séparé par ‘&’:

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

Ensuite, votre fonction de remplacement ressemblera à ceci:

 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 

Vous pourriez accélérer ceci au risque de faire des remplacements incorrects:

 qs = QueryDict(args) return value.replace(qs.get('cherche',''), qs.get('remplacement','')) 

Pas possible selon cette section de la documentation:

Les filtres personnalisés ne sont que des fonctions Python qui prennent un ou deux arguments:

  • La valeur de la variable (input) – pas nécessairement une chaîne.
  • La valeur de l’argument – cela peut avoir une valeur par défaut ou être complètement omis.

Au lieu d’un filtre, enregistrez votre tag en tant que simple étiquette. Ceux-ci peuvent prendre plusieurs arguments. La syntaxe pour l’invoquer sera un peu différente, mais ce n’est que du sucre syntaxique.

C’est facile comme ça.

 @register.filter(name='one_more') def one_more(_1, _2): return _1, _2 def your_filter(_1_2, _3) _1, _2 = _1_2 print "now you have three arguments, enjoy" {{ _1|one_more:_2|your_filter:_3 }} 

Cette fonctionnalité a été marquée comme WONTFIX en 2013 Trace de Django: http://code.djangoproject.com/ticket/1199

/globaltags/replace.py

 from django.template import Library import re register = Library() def search(value, search): return re.sub(search, '#f4x@SgXXmS', value) def replace(value, replace): return re.sub('#f4x@SgXXmS', replace, value) register.filter(search) register.filter(replace) 

Dans le template:

 {{ "saniel"|search:"s"|replace:"d" }} 

Heres une mauvaise idée mais fonctionne:

 {{ xml|input_by_xpath:"{'type':'radio','xpath':'//result/value'}" }} 

et

 @register.filter def input_by_xpath(device, args): args = eval(args) ... result = ""%(args['type'],value,args['xpath']) return mark_safe(result)