Pytanie Szablony Django: Jeśli fałsz?


Jak sprawdzić, czy zmienna jest Fałszywy używając składni szablonu Django?

{% if myvar == False %}

Wydaje się nie działać.

Zauważ, że bardzo chcę sprawdzić, czy ma on wartość Pythona False. Ta zmienna może również być pustą tablicą, która jest nie co chcę sprawdzić.


47
2017-11-19 21:02


pochodzenie


Posiadanie zmiennej w kontekście szablonu, która może być zarówno listą, jak i wartością logiczną, wydaje się być niewłaściwym podejściem w pierwszej kolejności? - Risadinha
@Risadinha Nie pamiętam mojego przypadku użycia. Możesz mieć racje. - mpen
{% if not myvar%} na pewno działa w Django 1.11, ale nie jestem już tak daleko od ciebie! - Ibo
@Ibo Dość pewnie not myvar sprawdza, czy myvar jest falsey, nie False. Zobacz też - mpen
@mpen, więc jeśli myvar był booleanem, not myvar wróci True jeśli został wysłany do szablonu jako zmienna kontekstowa przez funkcję renderowania, niezależnie od jej wartości (true lub false)? w tym przypadku należy sprawdzić 2 rzeczy: 1-myvar zostało dostarczone do funkcji renderowania, 2-jaką wartość myvar ma zapewniony. Będzie to dość skomplikowane, jeśli myvar jest raczej instancją klasy, słownikiem, obiektem itp. niż klasyczną zmienną. - Ibo


Odpowiedzi:


Django 1.10 (Informacje o wydaniu) dodano is i is not operatory porównania do if etykietka. Ta zmiana sprawia, że ​​testowanie tożsamości w szablonie jest bardzo proste.

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'

Jeśli używasz starszego Django, to od wersji 1.5 (Informacje o wydaniu) silnik szablonowy interpretuje True, False i None jako odpowiadające obiekty Pythona.

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'

Chociaż nie działa tak, jak można by się tego spodziewać.

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

21
2018-05-05 15:23



Przyjmie to, aby przenieść się na szczyt, a inne osoby używające aktualnych wersji mogą je znaleźć :-) - mpen
Uruchamiam problem, gdy moja zmienna kontekstowa zawiera liczbę całkowitą 0 (zero). Kiedy jest renderowany przez django, interpretowany jest jako "False". Wygląda na to, że nadal potrzebuję niestandardowego tagu szablonu, takiego jak sugerował Gabriel Hurley. - ceasaro
Lub możesz jawnie sprawdzić, czy zmienna ma wartość 0, ale może znacznik szablonu jest mniej szczegółowy. - Martin


Dla potomności mam kilka NullBooleanFields i oto co robię:

Aby sprawdzić, czy to jest True:

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

Aby sprawdzić, czy to jest False (zauważ, że to działa, ponieważ są tylko 3 wartości - Prawda / Fałsz / Brak):

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

Aby sprawdzić, czy to jest None:

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

Nie jestem pewien dlaczego, ale nie mogę tego zrobić variable == False, ale mogę zrobić variable == None.


29
2017-07-26 21:08



Ładniejszy idiom (zalecane przez PEP 8, porównania z singletonami takimi jak None powinny zawsze być zakończone is lub is not, nigdy operatorzy równości), aby sprawdzić Nones używa is, ponieważ None jest singleton - Humphrey Bogart
@Beau: szablony Django nie są kodami Pythona. To nie jest operator "jest" w szablonowym wyrażeniu warunkowym. - Ville Laurikari
To powinno być gdzieś w książce. Wiele osób korzysta z models.NullBooleanField() - Sevenearths


Możesz napisać niestandardowy filtr szablonu, aby zrobić to w kilku liniach kodu:

from django.template import Library

register = Library()

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

Następnie w swoim szablonie:

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

Oczywiście możesz uczynić ten znacznik szablonu znacznie bardziej ogólnym ... ale to pasuje do twoich potrzeb ;-)


21
2017-11-19 22:53



Nie wiedziałem, że możesz użyć filtrów ifs. Fajne :) Naprawdę pominąłem problem, używając "None" jako mojej fałszywej wartości zamiast .. ale dobrze wiedzieć na przyszłość. - mpen
Każdego dnia staram się uczyć czegoś nowego ... cieszę się, że mogłem się dzielić ;-) - Gabriel Hurley
docs.djangoproject.com/en/dev/ref/templates/builtins/#yesno - Matt


Myślę, że to zadziała dla Ciebie:

{% if not myvar %}

16
2017-11-25 12:52



Pytanie szczegółowo wymienione sprawdzanie False tylko wartości i powinien nie być wyzwalane przez puste tablice. Dotyczy to obu. - Shawn Chin


W starej wersji możesz używać tylko ifequal lub ifnotequal

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

Przykład:

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

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

Podobnie jak w znaczniku if, klauzula {% else%} jest opcjonalna.

Argumenty mogą być sztywno zakodowanymi ciągami, więc poniższe jest prawidłowe:

{% ifequal user.username "adrian"%}     ... {% endifequal%} Alternatywą dla znacznika ifequal jest użycie znacznika if i operatora ==.

ifnotequal Podobnie jak ifequal, poza tym testuje, że te dwa argumenty nie są równe.

Alternatywą dla znacznika ifnotequal jest użycie znacznika if i operatora! =.

Jednak teraz możemy użyć, jeśli / else łatwo

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

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

Wyrażenia złożone

Wszystkie powyższe elementy można łączyć, tworząc złożone wyrażenia. W przypadku takich wyrażeń może być ważne, aby wiedzieć, w jaki sposób operatorzy są grupowani, gdy wyrażenie jest oceniane - czyli zasady pierwszeństwa. Pierwszeństwo operatorów, od najniższego do najwyższego, jest następujące:

  • lub
  • i
  • nie
  • w
  • ==,! =, <,>, <=,> =

Więcej szczegółów

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


7
2017-07-18 11:45



Nie widzę żadnej wzmianki o sprawdzaniu fałszywości. Jest False obsługiwane słowo kluczowe? - mpen


Wpadłem na to jeszcze raz (pewien, że miałem wcześniej i zaproponowałem rozwiązanie mniej satysfakcjonujące).

Dla semantycznego semantycznego boolowskiego (na przykład użycie models.NullBooleanField), działa to dobrze:

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

Lub jeśli wolisz podekscytować się tym wszystkim ...

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

Tak czy inaczej, to obsługuje specjalny warunek, w którym nie dbasz o None (oceniając False w bloku if) lub True walizka.


5
2017-10-08 19:06



Działa doskonale z polami Boolean! Dzięki! - JDavies


Miałem wcześniej ten problem, który rozwiązałem za pomocą zagnieżdżonych instrukcji if, najpierw sprawdzając typ none oddzielnie.

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

Jeśli chcesz tylko sprawdzić, czy jest to fałsz, to po prostu

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

EDIT: Wydaje się działać.

{% 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 %}

Teraz tablice o zerowej długości są rozpoznawane jako takie; Brak typów jako Brak; faluje jak Fałsz; Trues jako trues; łańcuchy / tablice powyżej długości 0 jako prawdziwe.

Można również uwzględnić w kontekście zmienną false_list = [False,], a następnie zrobić

{% if some_bool in false_list %}False {% endif %}

3
2017-11-19 21:09



To rozróżnia None i False ale nie [] który również jest fałszywy. - mpen
Cóż, miałem do czynienia z renderowaniem zmiennej, która zawsze miała wartość NullBooleanField, (None / True / False). Wierzę, że mógłbyś go rozszerzyć w ten sam sposób; np. {% if some_bool == []%} {% else%} ... chociaż w tym momencie zaczyna wyglądać bardzo brzydko i może warto napisać własny tag szablonu. docs.djangoproject.com/en/dev/howto/custom-template-tags - dr jimbob
Czy to nawet rozpoznaje []? Nie rozpoznaje False. Bardzo smutne, że musiałbym napisać własną etykietę do tego szablonu: \ - mpen
@ Mark zobacz edycję powyżej; możesz zrobić {% jeśli 0 == a | długość%} zamiast {% jeśli some_bool == []%}. Właściwie przetestowany i działa zgodnie z oczekiwaniami. - dr jimbob
Dobra edycja ... to na pewno jeden sposób na zrobienie tego. Wygląda jednak dość nieprzyjemnie :) Myślę, że nowy tag szablonu byłby mniejszym złem. - mpen


Spójrz na tak nie pomocnik

Na przykład:

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

3
2017-11-27 10:49



Nie. Na pewno chciałem umieścić tam cały blok, a nie tylko prosty ciąg. - mpen