2013-04-02 17 views
6

Mi piacerebbe utilizzare sempre un valore positivo della mia variabile in un modello Django. segno della variabile è solo un significato testuale:Moltiplica per -1 in un modello Django

{% if qty > 0 %} 
    Please, sell {{ qty }} products. 
{% elif qty < 0 %} 
    Please, buy {{ -qty }} products. 
{% endif %} 

Naturalmente, {{ -qty }} non funziona.

Esiste una soluzione alternativa senza passare una seconda variabile contenente il valore assoluto? Qualcosa come un filtro modello che converte il valore in un numero intero senza segno.

Grazie!

risposta

11

È possibile abusare di alcuni filtri stringa:

{% if qty > 0 %} 
    Please, sell {{ qty }} products. 
{% elif qty < 0 %} 
    Please, buy {{ qty|slice:"1:" }} products. 
{% endif %} 

o

Please, sell {{ qty|stringformat:"+d"|slice:"1:" }} products. 

Ma probabilmente si dovrebbe fare secondo lei o scrivere un filtro personalizzato.

+0

Grazie, sembra che questo sia quello che stavo cercando! Potrei usare un filtro personalizzato (ma preferisco "abusare" di quelli di Django), ma non mi piace l'idea di fare qualcosa di più nella vista. A mio parere, la vista fa già la logica, ed è compito del modello rendere il significato testuale (e forse voglio un codice HTML diverso per entrambi i casi). Inoltre, non mostrare il segno di un numero è solo formattazione, non calcoli. Ma sfortunatamente, non possiamo usare 'stringformat:" u "' per farlo. – alexpirine

1

Idealmente si dovrebbe eseguire il controllo nella vista, la logica separata dal display (ad esempio, cosa succede se qty = 0?) Se ti ostini a fare matematica nel modello, si potrebbe fare qualcosa di simile this hack.

Un'altra opzione è scrivere un filtro personalizzato (vedere this example).

+0

Il caso 'qty = 0 'è, ovviamente, incluso nel modello originale, ma non mostrato qui per ragioni di semplicità. Non mi piace l'idea di scrivere più cose a mio avviso, perché penso che faccia la logica e trasmetta i risultati in modo molto conciso.Se domani voglio usare un diverso stile HTML per entrambi i casi, non penso che dovrebbe essere fatto nella vista! – alexpirine

+0

Abbastanza giusto. In tal caso, ti consiglio di scrivere il tuo filtro modello, come suggeriscono alcune delle altre risposte. Bastano poche righe di codice e questa funzionalità sarà facilmente implementabile in tutti i tuoi modelli. – Basti

4

È necessario utilizzare un filtro personalizzato per questo.

Ecco due modi per farlo:

1) È possibile definire un filtro negate:

# negate_filter.py 
from django import template 
register = template.Library() 

@register.filter 
def negate(value): 
    return -value 

Poi, nel vostro template, aggiungere il codice {% load negate_filter %} verso l'alto e quindi sostituire {{ -qty }} con {{ qty|negate }} .

2) È inoltre possibile sostituire l'intera cosa con uno buy_sell filtro se vuoi:

# buy_sell_filter.py 
from django import template 
register = template.Library() 

@register.filter 
def buy_sell(value): 
    if value > 0 : 
     return 'sell %s' % value 
    else : 
     return 'buy %s' % -value 

Poi il modello dovrebbe essere solo

{% if qty %} Please, sell {{ qty|buy_sell }} products.{% endif %} 

Si potrebbe anche includere l'intera stringa nel filtro e basta che l'intero modello sia {{qty | buy_sell}}.

Entrambe le opzioni sono ragionevoli, a seconda del resto del modello. Ad esempio, se hai un sacco di stringhe che usano buy per il negativo e vendi per il positivo, fai il secondo.

2

Come con everything in Python, esiste una libreria per questo: django-mathfilters.

allora si può semplicemente utilizzare il filtro abs in questo modo:

Please, sell {{ qty|abs }} products. 
Problemi correlati