كيفية الحصول على وظيفة بيان "حالة التبديل" في قوالب django؟

StackOverflow https://stackoverflow.com/questions/725771

سؤال

لقد وجدت ال حلقة الوصل للحصول على علامة "تبديل" في قوالب Django، لكنني كنت أتساءل عما إذا كان هذا قد يتحقق بطريقة ما دون ذلك. باستخدام فقط الأشياء التي تأتي مع django؟ في الأساس هل هناك طريقة أخرى، ثم باستخدام بيانات "إذا" أو "ifequal"؟

شكرا مقدما على أي نصائح / اقتراحات.

هل كانت مفيدة؟

المحلول

لسوء الحظ، هذا غير ممكن مع محرك قالب DJANGO الافتراضي. سيكون عليك أن تكتب شيئا قاسيا مثل هذا لمحاكاة مفتاح.

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

أو إذا كان واحد فقط إذا كان الشرط صحيحا ولا تحتاج إلى افتراضي.

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

عادة، عندما يكون محرك القالب غير قوي بما يكفي لإنجاز ما تريد أن تكون علامة على أنه يجب نقل الكود إلى عرض Django بدلا من القالب. علي سبيل المثال:

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

# Template
{{ val }}

نصائح أخرى

اعتبارا من django 1.4، هناك {% elif %}:

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

إلى المستجيبين السابقين: بدون فهم حالة الاستخدام، فقد وصلت إلى افتراضات وانتقدت السائل. يقول Vber "في جميع أنحاء المكان" والتي ليس بالتأكيد ضمنا من قبل السائل. ليس عدلا.

لدي حالة حيث أود القيام به {% switch %} بيان في مكان واحد بالضبط في قالب Django الخاص بي. ليس فقط غير مناسب لنقل ما يعادل بيان التبديل إلى رمز Python، ولكن ذلك من شأنه أن يقوم في الواقع بإجراء العرض والقالب أصعب القراءة واتخاذ منطق مشروط بسيط ينتمي إلى مكان واحد وتقسيمه إلى مكانين.

في كثير من الحالات التي يمكن أن أتخيل {% switch %} (أو {% if %}) أن تكون مفيدة، لا تستخدم المرء يتطلب وضع HTML في طريقة عرض. هذه هي خطيئة أسوأ بكثير وهذا هو السبب {% if %} موجود في المقام الأول. {% switch %} ليس مختلفا

لحسن الحظ، يتم توسيع Django وينفذ عدة أشخاص التبديل. الدفع:

تبديل علامة القالب

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 ""

في رأي عام للغاية، فإن الحاجة إلى بيان التبديل هي علامة على وجود حاجة لإنشاء فئات وأشياء جديدة تلتقط "الحالات" المختلفة.

ثم، بدلا من "Swtich" في كل مكان، تحتاج فقط إلى استدعاء أسلوب كائن أو مرجع سمة كائن ويتم ذلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top