Frage

fand ich einen Link einen ‚Schalter‘ -Tag in Django-Vorlagen zu haben, aber ich wenn dies frage mich irgendwie, ohne sie erreicht werden. Mit nur die Sachen, die mit Django kommt? Grundsätzlich ist es auch andere Art und Weise dann mehrere mit ‚wenn‘ oder "IfEqual Aussagen?

Vielen Dank im Voraus für alle Tipps / Vorschläge.

War es hilfreich?

Lösung

Leider ist dies nicht möglich, mit der Standard-Django Template-Engine. Sie werden hässlich, etwas zu schreiben haben, wie diese einen Schalter zu emulieren.

{% if a %}
    {{ a }}
{% else %}
    {% if b %}
        {{ b }}
    {% else %}
        {% if c %}
            {{ c }}
        {% else %}
            {{ default }}
        {% endif %}
    {% endif %}
{% endif %}

oder wenn nur ein, wenn die Bedingung wahr sein kann und Sie keinen Standard benötigen.

{% if a %}
{{ a }}
{% endif %}
{% if b %}
{{ b }}
{% endif %}
{% if c %}
{{ c }}
{% endif %}

Normalerweise, wenn der Template-Engine ist nicht stark genug, zu erreichen, was Sie wollen, ist dies ein Zeichen ist, dass der Code in Django Ansicht bewegt werden soll, anstatt in der Vorlage. Zum Beispiel:

# Django view
if a:
  val = a
elif b:
  val = b
elif c:
  val = c
else:
  val = default

# Template
{{ val }}

Andere Tipps

Wie von Django 1.4, gibt es {% elif %}:

{% if a %}
  thing
{% elif b %}
  other thing
{% elif c %}
  another thing
{% endif %} 

Zu den vorherigen Responder: Ohne den Anwendungsfall zu verstehen, haben Sie Annahmen gemacht und kritisiert den Fragesteller. @Ber sagt „ganz über den Platz“, das vom Fragesteller implizit schon gar nicht ist. Nicht fair.

Ich habe einen Fall, in dem Ich mag würde eine {% switch %} Anweisung in genau einen Platz in meiner Django-Vorlage zu tun. Nicht nur ist es nicht zweckmäßig, das Äquivalent der switch-Anweisung in Python-Code zu bewegen, aber das wäre tatsächlich sowohl die Aussicht und die Vorlage schwieriger zu lesen und nehmen einfache bedingte Logik, die an einem Ort gehört, und spaltete es in zwei Orten.

In vielen Fällen, in denen ich ein {% switch %} vorstellen konnte (oder {% if %}) nützlich sein, nicht mit einem erfordert in einer Ansicht HTML setzen. Das ist eine viel schlimme Sünde und deshalb {% if %} in erster Linie existiert. {% switch %} ist das nicht anders.

Zum Glück ist Django erweiterbar und mehr Personen haben Schalter implementiert. Check out:

Template-Tag wechseln

from django import template
from django.template import Library, Node, VariableDoesNotExist

register = Library()


@register.tag(name="switch")
def do_switch(parser, token):
    """
    The ``{% switch %}`` tag compares a variable against one or more values in
    ``{% case %}`` tags, and outputs the contents of the matching block.  An
    optional ``{% else %}`` tag sets off the default output if no matches
    could be found::

        {% switch result_count %}
            {% case 0 %}
                There are no search results.
            {% case 1 %}
                There is one search result.
            {% else %}
                Jackpot! Your search found {{ result_count }} results.
        {% endswitch %}

    Each ``{% case %}`` tag can take multiple values to compare the variable
    against::

        {% switch username %}
            {% case "Jim" "Bob" "Joe" %}
                Me old mate {{ username }}! How ya doin?
            {% else %}
                Hello {{ username }}
        {% endswitch %}
    """
    bits = token.contents.split()
    tag_name = bits[0]
    if len(bits) != 2:
        raise template.TemplateSyntaxError("'%s' tag requires one argument" % tag_name)
    variable = parser.compile_filter(bits[1])

    class BlockTagList(object):
        # This is a bit of a hack, as it embeds knowledge of the behaviour
        # of Parser.parse() relating to the "parse_until" argument.
        def __init__(self, *names):
            self.names = set(names)
        def __contains__(self, token_contents):
            name = token_contents.split()[0]
            return name in self.names

    # Skip over everything before the first {% case %} tag
    parser.parse(BlockTagList('case', 'endswitch'))

    cases = []
    token = parser.next_token()
    got_case = False
    got_else = False
    while token.contents != 'endswitch':
        nodelist = parser.parse(BlockTagList('case', 'else', 'endswitch'))

        if got_else:
            raise template.TemplateSyntaxError("'else' must be last tag in '%s'." % tag_name)

        contents = token.contents.split()
        token_name, token_args = contents[0], contents[1:]

        if token_name == 'case':
            tests = map(parser.compile_filter, token_args)
            case = (tests, nodelist)
            got_case = True
        else:
            # The {% else %} tag
            case = (None, nodelist)
            got_else = True
        cases.append(case)
        token = parser.next_token()

    if not got_case:
        raise template.TemplateSyntaxError("'%s' must have at least one 'case'." % tag_name)

    return SwitchNode(variable, cases)

class SwitchNode(Node):
    def __init__(self, variable, cases):
        self.variable = variable
        self.cases = cases

    def __repr__(self):
        return "<Switch node>"

    def __iter__(self):
        for tests, nodelist in self.cases:
            for node in nodelist:
                yield node

    def get_nodes_by_type(self, nodetype):
        nodes = []
        if isinstance(self, nodetype):
            nodes.append(self)
        for tests, nodelist in self.cases:
            nodes.extend(nodelist.get_nodes_by_type(nodetype))
        return nodes

    def render(self, context):
        try:
            value_missing = False
            value = self.variable.resolve(context, True)
        except VariableDoesNotExist:
            no_value = True
            value_missing = None

        for tests, nodelist in self.cases:
            if tests is None:
                return nodelist.render(context)
            elif not value_missing:
                for test in tests:
                    test_value = test.resolve(context, True)
                    if value == test_value:
                        return nodelist.render(context)
        else:
            return ""

In einer sehr allgemeinen Ansicht, die Notwendigkeit für eine switch-Anweisung ist ein Zeichen, dass es eine Notwendigkeit, neue Klassen zu erstellen und dass die verschiedenen „Fälle“ Objekte erfassen.

Dann wird anstelle von „swtich“ ing ganz über dem Platz, müssen Sie nur eine Objektmethode aufzurufen oder ein Objektattribut und fertig zu verweisen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top