Come faccio ad aggiungere più argomenti al mio filtro modello personalizzato in un modello django?

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

  •  05-07-2019
  •  | 
  •  

Domanda

Ecco il mio filtro personalizzato:

from django import template

register = template.Library()

@register.filter
def replace(value, cherche, remplacement):
    return value.replace(cherche, remplacement)

e qui sono i modi in cui ho provato ad usarlo nel mio file modello che ha provocato un errore:

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

Ho esaminato django's docs e libro ma hai trovato solo un esempio usando un singolo argomento ... è persino possibile?

È stato utile?

Soluzione

È possibile e abbastanza semplice.

Django consente solo un argomento al tuo filtro, ma non c'è motivo per cui non puoi mettere tutti i tuoi argomenti in una singola stringa usando una virgola per separarli.

Ad esempio, se si desidera un filtro che controlli se la variabile X è nell'elenco [1,2,3,4], sarà necessario un filtro modello simile a questo:

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

Ora possiamo creare il tuo templatetag in questo modo:

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)

La linea che crea arg_list è un'espressione del generatore che divide la stringa args su tutte le virgole e chiama .strip () per rimuovere eventuali spazi iniziali e finali.

Se, ad esempio, il 3 ° argomento è un int allora basta fare:

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

O se sono tutti ints:

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

MODIFICA: ora per rispondere in modo specifico alla tua domanda utilizzando chiavi, coppie di valori come parametri, puoi utilizzare la stessa classe utilizzata da Django per analizzare le stringhe di query dagli URL, che ha anche il vantaggio di gestire correttamente la codifica dei caratteri in base al tuo settings.py.

Quindi, come per le stringhe di query, ogni parametro è separato da '& amp;':

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

Quindi la tua funzione di sostituzione ora apparirà così:

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

Potresti accelerarlo un po 'a rischio di fare sostituzioni errate:

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

Altri suggerimenti

Non possibile secondo questa sezione della documentazione:

I filtri personalizzati sono solo funzioni di Python che accettano uno o due argomenti:

  • Il valore della variabile (input) - non necessariamente una stringa.
  • Il valore dell'argomento - questo può avere un valore predefinito o essere del tutto escluso.

Invece di un filtro, registra il tuo tag come semplice tag. Quelli possono prendere più argomenti. La sintassi per invocarla sarà un po 'diversa, ma questo sta cambiando lo zucchero sintattico.

È facile così.

@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 }}

Questa funzione è stata contrassegnata come WONTFIX nel 2013 Trac di Django: http://code.djangoproject.com / biglietti / 1199

&

lt; & Il mio sito-gt; /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)

Nel modello:

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

Puoi semplicemente farlo:

{% assign find_total_issued = dailysalesreport | find: "TotalIssued":"13" %}

public static List<object> Find(object collection, string column, string value)

E raggiungerà la destinazione poiché l'astrazione della funzione è sjare.

Ecco una cattiva idea ma funziona:

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

e

@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)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top