Wie kann ich mehrere Argumente zu meinen benutzerdefinierten Vorlage Filter in einer django Vorlage hinzufügen?
-
05-07-2019 - |
Frage
Hier ist meine benutzerdefinierten Filter:
from django import template
register = template.Library()
@register.filter
def replace(value, cherche, remplacement):
return value.replace(cherche, remplacement)
und hier sind die Möglichkeiten, wie ich versuchte, es in meiner Vorlage-Datei, die in einem Fehler:
{{ attr.name|replace:"_"," " }}
{{ attr.name|replace:"_" " " }}
{{ attr.name|replace:"_":" " }}
{{ attr.name|replace:"cherche='_', remplacement=' '" }}
schaute ich in Djangos docs und Buch aber nur gefunden Beispiel ein einziges Argument ... ist es sogar möglich?
Lösung
Es ist möglich und relativ einfach.
Django kann immer nur ein Argument für die Filter, aber es gibt keinen Grund, warum Sie nicht alle Ihre Argumente in eine einzige Zeichenfolge mit einem Komma, sie trennen setzen können.
So zum Beispiel, wenn Sie einen Filter wollen, der überprüft, ob die Variable X in der Liste [1,2,3,4] Sie eine Vorlage Filter möchten, die wie folgt aussieht:
{% if X|is_in:"1,2,3,4" %}
Jetzt können wir Ihre TemplateTag wie folgt erstellen:
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)
Die Linie, die arg_list erzeugt ein Generator Ausdruck, der den args Zeichenfolge auf allen Kommata spaltet und ruft .strip () keine führende und nachgestellte Leerzeichen zu entfernen.
Wenn zum Beispiel das dritte Argument ist ein int dann nur tun:
arg_list[2] = int(arg_list[2])
Oder wenn alle von ihnen sind Ints tun:
arg_list = [int(arg) for arg in args.split(',')]
EDIT: jetzt speziell auf Ihre Frage zu beantworten, indem sie Schlüssel, Wert-Paare als Parameter verwenden, können Sie die gleiche Klasse verwenden Django Query-Strings aus URLs analysieren verwendet, die dann auch den Vorteil der Umgang mit Zeichencodierung richtig nach Ihren settings.py.
So, wie mit Query-Strings, die jeweils Parameter getrennt durch '&':
{{ attr.name|replace:"cherche=_&remplacement= " }}
Dann ersetzen Sie Ihre Funktion wird nun wie folgt aussehen:
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
Sie können dies auf einige auf der Gefahr dabei einigen falschen Ersatz beschleunigen:
qs = QueryDict(args)
return value.replace(qs.get('cherche',''), qs.get('remplacement',''))
Andere Tipps
Nicht möglich nach In diesem Abschnitt der docs:
Benutzerdefinierte Filter sind nur Python-Funktionen, die ein oder zwei Argumente:
- Der Wert der Variablen (Eingang) - nicht unbedingt ein String.
- Der Wert des Arguments - das kann eine haben Standardwert, oder ganz weggelassen werden.
Statt einem Filters, den Tag als einfacher Tag registrieren. Diese können mehrere Argumente. Die Syntax für den Aufruf, es wird ein wenig anders sein, aber das ist nur syntaktischer Zucker Wechsel.
Es ist einfach so.
@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 }}
Diese Funktion als WONTFIX wurde im Jahr 2013 Djangos Trac markiert: http://code.djangoproject.com / ticket / 1199
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)
In der Vorlage:
{{ "saniel"|search:"s"|replace:"d" }}
Sie können nur einfach dies tun:
{% assign find_total_issued = dailysalesreport | find: "TotalIssued":"13" %}
public static List<object> Find(object collection, string column, string value)
Und es wird das Ziel als die Abstraktion der Funktion ist sjare
erreichen.
Heres eine schlechte Idee, aber funktioniert:
{{ xml|input_by_xpath:"{'type':'radio','xpath':'//result/value'}" }}
und
@register.filter
def input_by_xpath(device, args):
args = eval(args)
...
result = "<input type=\"%s\" value=\"%s\" name=\"%s\"/>"%(args['type'],value,args['xpath'])
return mark_safe(result)