Wie kann ich mehrere Argumente zu meinen benutzerdefinierten Vorlage Filter in einer django Vorlage hinzufügen?

StackOverflow https://stackoverflow.com/questions/420703

  •  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?

War es hilfreich?

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

/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)

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)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top