web-dev-qa-db-fra.com

Django modèles: si faux?

Comment vérifier si une variable est False en utilisant Django syntaxe du modèle?

{% if myvar == False %}

Ne semble pas fonctionner.

Notez que je veux très spécifiquement vérifier s'il a la valeur Python False. Cette variable pourrait aussi être un tableau vide, qui est pas ce que je veux vérifier.

58
mpen

Django 1.10 (notes de version) a ajouté les is et is not opérateurs de comparaison avec la balise if. Cette modification rend les tests d'identité dans un modèle assez simples.

In[2]: from Django.template import Context, Template

In[3]: context = Context({"somevar": False, "zero": 0})

In[4]: compare_false = Template("{% if somevar is False %}is false{% endif %}")
In[5]: compare_false.render(context)
Out[5]: u'is false'

In[6]: compare_zero = Template("{% if zero is not False %}not false{% endif %}")
In[7]: compare_zero.render(context)
Out[7]: u'not false'

Si vous utilisez un ancien Django alors à partir de la version 1.5 (notes de version) le moteur de modèle interprète True, False et None comme objets Python correspondants.

In[2]: from Django.template import Context, Template

In[3]: context = Context({"is_true": True, "is_false": False, 
                          "is_none": None, "zero": 0})

In[4]: compare_true = Template("{% if is_true == True %}true{% endif %}")
In[5]: compare_true.render(context)
Out[5]: u'true'

In[6]: compare_false = Template("{% if is_false == False %}false{% endif %}")
In[7]: compare_false.render(context)
Out[7]: u'false'

In[8]: compare_none = Template("{% if is_none == None %}none{% endif %}")
In[9]: compare_none.render(context)
Out[9]: u'none'

Bien que cela ne fonctionne pas comme on pourrait s'y attendre.

In[10]: compare_zero = Template("{% if zero == False %}0 == False{% endif %}")
In[11]: compare_zero.render(context)
Out[11]: u'0 == False'
27
Martin

Pour la postérité, j'ai quelques NullBooleanFields et voici ce que je fais:

Pour vérifier s'il s'agit de True:

{% if variable %}True{% endif %}

Pour vérifier si c'est False (notez que cela fonctionne car il n'y a que 3 valeurs - True/False/None):

{% if variable != None %}False{% endif %}

Pour vérifier s'il s'agit de None:

{% if variable == None %}None{% endif %}

Je ne sais pas pourquoi, mais je ne peux pas faire variable == False, mais je peux faire variable == None.

32
Bialecki

Vous pouvez écrire un filtre de modèle personnalisé pour le faire dans une demi-douzaine de lignes de code:

from Django.template import Library

register = Library()

@register.filter
def is_false(arg): 
    return arg is False

Puis dans votre modèle:

{% if myvar|is_false %}...{% endif %}

Bien sûr, vous pouvez rendre cette balise de modèle beaucoup plus générique ... mais cela convient spécifiquement à vos besoins ;-)

22
Gabriel Hurley

Je pense que cela fonctionnera pour vous:

{% if not myvar %}
21
Zubair Afzal

Dans l'ancienne version, vous ne pouvez utiliser que ifequal ou ifnotequal

{% ifequal YourVariable ExpectValue %}
    # Do something here.
{% endifequal %}

Exemple:

{% ifequal userid 1 %}
  Hello No.1
{% endifequal %}

{% ifnotequal username 'Django' %}
  You are not Django!
{% else %}
  Hi Django!
{% endifnotequal %}

Comme dans la balise if, une clause {% else%} est facultative.

Les arguments peuvent être des chaînes codées en dur, donc ce qui suit est valide:

{% ifequal user.username "adrian"%} ... {% endifequal%} Une alternative à la balise ifequal est d'utiliser la balise if et l'opérateur ==.

ifnotequal Tout comme ifequal, sauf qu'il teste que les deux arguments ne sont pas égaux.

Une alternative à la balise ifnotequal consiste à utiliser la balise if et l'opérateur! =.

Cependant, nous pouvons maintenant utiliser if/else facilement

{% if somevar >= 1 %}
{% endif %}

{% if "bc" in "abcdef" %}
  This appears since "bc" is a substring of "abcdef"
{% endif %}

Expressions complexes

Tout ce qui précède peut être combiné pour former des expressions complexes. Pour de telles expressions, il peut être important de savoir comment les opérateurs sont regroupés lorsque l'expression est évaluée, c'est-à-dire les règles de priorité. La priorité des opérateurs, du plus bas au plus élevé, est la suivante:

  • ou
  • et
  • ne pas
  • dans
  • ==,! =, <,>, <=,> =

Plus de détails

https://docs.djangoproject.com/en/dev/ref/templates/builtins/

9
Marvin W

Je suis juste tombé sur cela à nouveau (certain que j'avais auparavant et trouvé une solution moins que satisfaisante).

Pour une sémantique booléenne à trois états (par exemple, en utilisant models.NullBooleanField), cela fonctionne bien:

{% if test.passed|lower == 'false' %} ... {% endif %}

Ou si vous préférez vous exciter par rapport à tout cela ...

{% if test.passed|upper == 'FALSE' %} ... {% endif %}

Dans les deux cas, cela gère la condition spéciale dans laquelle vous ne vous souciez pas du cas None (évalué à False dans le bloc if) ou True.

5
Ian Schneider

J'ai déjà rencontré ce problème, que j'ai résolu en imbriquant si les instructions vérifiaient d'abord séparément aucun type.

{% if object.some_bool == None %}Empty
{% else %}{% if not object.some_bool %}False{% else %}True{% endif %}{% endif %}

Si vous voulez seulement tester si c'est faux, alors

{% if some_bool == None %}{% else %}{% if not some_bool %}False{% endif %}{% endif %}

EDIT: Cela semble fonctionner.

{% if 0 == a|length %}Zero-length array{% else %}{% if a == None %}None type{% else %}{% if not a %}False type{% else %}True-type {% endif %}{% endif %}{% endif %}

Désormais, les tableaux de longueur nulle sont reconnus comme tels; Aucun type comme Aucun type; fausses comme Faux; Les vrais comme les vrais; les chaînes/tableaux au-dessus de la longueur 0 sont vrais.

Vous pouvez également inclure dans le contexte une variable false_list = [False,] puis faire

{% if some_bool in false_list %}False {% endif %}
4
dr jimbob

Regardez l'aide yesno

Par exemple:

{{ myValue|yesno:"itwasTrue,itWasFalse,itWasNone" }}
4
mwjackson

Je viens de trouver ce qui suit qui semble bon dans Django 1.8

Essayez ceci au lieu de la valeur n'est pas faux:

if value|stringformat:'r' != 'False'

Essayez ceci au lieu de la valeur True:

if value|stringformat:'r' == 'True'

sauf si vous avez vraiment joué avec les méthodes repr pour faire ressembler la valeur à un booléen, je pense que cela devrait vous donner une assurance suffisamment ferme que la valeur est vraie ou fausse.

3
Danimal

Ceci est beaucoup plus facile à archiver Python (c'est-à-dire votre code d'affichage) que dans le modèle, car le code Python est simplement:

myvar is False

Illustrant:

>>> False is False
True
>>> None is False
False
>>> [] is False
False

Le problème au niveau du modèle est que le modèle if n'analyse pas is (bien qu'il analyse in). De plus, si cela ne vous dérange pas, vous pouvez essayer de patcher la prise en charge de is dans le moteur de modèle; le baser sur le code pour ==.

2
Mike DeSimone