Bedingte Anweisungen und Verzweigungen in Django-Templates

  • 7. Februar 2022

Django-Templates sind ein Mix aus statischem HTML und einer speziellen Syntax, die es erlaubt, dynamischen Code einzufügen. Mit Template-Tags ist es möglich, Logik in den Renderprozess einzubringen. Bedingte Anweisungen wie if-Statements, Verzweigungen mit if...else sowie mehrfache Verzweigungen mit if...elif...else sind möglich.

Template-Tags ermöglichen Django, komplexe Operationen während des Renderns des HTML auszuführen. Dazu gehört das Erzeugen von Text, das Ausführen von Schleifen mit for-Loops oder das Auswerten von Logik mittels if...elif...else-Anweisungen. Wie das im Detail aussieht, beschreibe ich in diesem Blog-Post.

Bedingte Anweisungen

Das {% if %}-Tag evaluiert eine Variable danach, ob sie wahr ist und gibt True zurück, wenn dies der Fall ist.

Das if-Tag sieht so aus:

{% if <Bedingung> %}
    Wenn-Code
{% endif %}

Ein Beispiel:

{% if user.is_authenticated %} 
    Hallo {{ user.username }}
{% endif %}

Die obige bedingte Anweisung evaluiert, ob der Benutzer an der Web-App angemeldet ist und gibt, wenn das der Fall ist, True zurück. Im obigen Beispiel wird die Zeichenkette «Hallo» ausgegeben, gefolgt vom Benutzernamen. Ist der Benutzer nicht angemeldet, wird nichts ausgegeben.

Verzweigungen

Wir können diese Anweisung um eine else-Anweisung erweitern, um mehr Kontrolle über die Ausgabe zu haben. Die Syntax für eine Verzweigung ist wie folgt:

{% if <Bedingung> %}
    Wenn-Code
{% else %}
    Dann-Code
{% endif %}

Auch hier ein Beispiel dazu:

{% if user.is_authenticated %} 
    Hallo {{ user.username }}
{% else %}
    Hallo Gast
{% endif %}

Mit diesem Code wird evaluiert, ob der Benutzer angemeldet ist. Ist das nicht der Fall, wird die Zeichenkette Hallo Gast ausgegeben.

Mehrfache Verzweigungen

Auch mehrfache Verzweigungen sind möglich. Die Syntax dafür sieht so aus:

{% if <Bedingung1> %}
    Wenn-Code für Bedingung1
{% elif <Bedingung2> %}
    Wenn-Code für Bedingung2
{% else %}
    Dann-Code
{% endif %}

Nehmen wir für diesen Fall ein neues Beispiel. In der Schweiz fahren Kinder bis sechs Jahre mit den Schweizer Bundesbahnen gratis mit. Bis 16 Jahren bezahlen Sie dann den halben Tarif und danach den vollen Betrag. Diese Logik können wir mit folgender mehrfacher Verzweigung abfragen:

{% if alter < 6 %}
  Du darfst gratis mit!
{% elif alter < 16 %}
  Du bezahlst nur den halben Preis!
{% else %}
  Du bezahlst den vollen Preis.
{% endif %}

Vergleiche und logische Operatoren

Die {% if %}, {% elif %}, {% else %}-Tags in Django-Templates erlauben, analog zu Python, den Einsatz von logischen Operatoren.

Ist gleich

{% if var1 == "x" %}
  Diese Zeichenkette wird ausgegeben, wenn die Variable "var1" gleich "x" ist.
{% endif %}

Ist ungleich

{% if var1 != "x" %}
  Diese Zeichenkette wird ausgegeben, wenn die Variable "var1" ungleich "x" ist oder die Variable "var1" nicht im Template-Kontext gefunden wurde. 
{% endif %}

Kleiner als

{% if var1 < 100 %}
  Diese Zeichenkette wird ausgegeben, wenn "var1" weniger als 100 ist.
{% endif %}

Kleiner oder gleich als

{% if var1 <= 100 %}
  Diese Zeichenkette wird ausgegeben, wenn "var1" weniger oder gleich 100 ist.
{% endif %}

Grösser als

{% if var1 > 0 %}
  Diese Zeichenkette wird ausgegeben, wenn "var1" grösser als 0 ist.
{% endif %}

Grösser oder gleich als

{% if somevar >= 1 %}
  Diese Zeichenkette wird ausgegeben, wenn "var1" grösser oder gleich 1 ist.
{% endif %}

In und not in

Mit in und not in wird getestet, ob sich ein Wert in einer Zeichenkette, Liste, Set, Dictionary oder einem QuerySet befindet.

{% if "bc" in "abcdef" %}
  Wird angezeigt, wenn "bc" eine Teilmenge der Zeichenkette "abcdef" ist"
{% endif %}
{% if "hallo" in gruesse %}
  Wird angezeigt, wenn "gruesse" eine Liste oder ein Set ist und ein Element davon "hallo" entspricht.
{% endif %}
{% if adresse in adressen %}
  Wird angezeigt, wenn "adresse" eine Instanz eines QuerySets namens "adressen" ist. 
{% endif %}

Und

{% if var1 and var2 %}
    Wird angezeigt, wenn "var1" und "var2" wahr sind.
{% endif %}

Oder

{% if var1 or var2 %}
    Wird angezeigt, wenn "var1" oder "var2" wahr ist.
{% endif %}

Nicht

{% if not var1 %}
    Wird angezeigt, wenn "var1" nicht wahr ist, sprich den Wert False, None, 0, oder "" (leere Zeichenkette) hat. 
{% endif %}

Komplexe Ausdrücke

Auch sind komplexe Ausdrücke mit or und and, möglich. Es gelten die Präzedenzregeln von Python. Ein Beispiel:

{% if a == b or c == d and e %}

Dieser Ausdruck wird interpretiert als:

{% if (a == b) or ((c == d) and e) %}

Es empfiehlt sich für die bessere Lesbarkeit, das gleich so hinzuschreiben.

Aufgepasst: Vergleichsoperatoren können nicht, anders als in Python, «verkettet» werden. Das heisst anstelle von {% if a > b > c %}, schreibe den Vergleich als {% if a > b and b > c %}.

Wie in Python werden auch Template-Tags von links nach rechts evaluiert und werden, ebenfalls wie in Python, nach dem Prinzip der Kurzschlussauswertung (Short-Circuit Evaluation) ausgewertet.

Geschäftslogik und Templates

Auch wenn es verlockend ist, halte Geschäftslogik, wenn immer möglich, aus den Templates raus. So etwa obiges Beispiel mit der SBB. Die Evaluation von Fahrgast-Tarifen gehört nicht in das Template. Verwalte Geschäftslogik im View oder sogar auf Ebene der Datenbank-Modelle. Templates sind die Präsentationsschicht von Django und damit zuständig für die Darstellung von Inhalten und die Benutzerinteraktion.