2009-04-07 16 views
22

मुझे Django टेम्पलेट्स में 'स्विच' टैग रखने के लिए link मिला, लेकिन मैं सोच रहा था कि इसे किसी भी तरह से हासिल किया जा सकता है या नहीं। Django के साथ आता है कि केवल सामान का उपयोग करना? मूल रूप से कई 'if' या 'ifequal' कथन का उपयोग करके कोई अन्य तरीका है?Django टेम्पलेट्स में 'स्विच-केस' कथन कार्यक्षमता कैसे प्राप्त करें?

किसी भी सुझाव/सुझाव के लिए अग्रिम धन्यवाद।

+0

+1 लिंक के लिए धन्यवाद, लेकिन वे कहते हैं कि टेम्पलेट्स 'प्रोग्रामिंग' और व्यापार तर्क के लिए नहीं है –

उत्तर

21

दुर्भाग्यवश, डिफ़ॉल्ट 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 }} 
+10

Django 1.4 के रूप में, elif समर्थित है –

+1

'firstof' टेम्पलेट फ़िल्टर देखें, जो इसे संक्षिप्त करता है। मुझे यकीन नहीं है कि इसे कब पेश किया गया था। – chris

2

एक बहुत ही सामान्य दृश्य में, एक स्विच बयान के लिए की जरूरत नई कक्षाएं बनाने के लिए की जरूरत है और उस पर कब्जा अलग "मामलों" वस्तुओं है कि एक संकेत है।

फिर, जगह पर "swtich" ing के बजाय, आपको केवल एक ऑब्जेक्ट विधि कॉल करने या किसी ऑब्जेक्ट विशेषता को संदर्भित करने और आपके द्वारा किए जाने की आवश्यकता है।

+0

एक ओओपी भाषा में समझ में आता है, लेकिन Django टेम्पलेट भाषा में नहीं। Django टेम्पलेट में प्रतिपादन करने के लिए आप "ऑब्जेक्ट विधि को कॉल नहीं कर सकते" नहीं कर सकते हैं। –

16

पिछले उत्तरदाताओं को: उपयोग के मामले को समझने के बिना, आपने धारणाएं की हैं और प्रश्नकर्ता की आलोचना की है। @ बेर कहते हैं "सभी जगह" जो निश्चित रूप से प्रश्नकर्ता द्वारा निहित नहीं है। निष्पक्ष नहीं।

मेरे पास एक ऐसा मामला है जहां मैं अपने Django टेम्पलेट में एक ही स्थान पर {% switch %} कथन करना चाहता हूं। न केवल स्विच स्टेटमेंट के बराबर को पाइथन कोड में स्थानांतरित करना सुविधाजनक नहीं है, बल्कि यह वास्तव में दृश्य और टेम्पलेट दोनों को पढ़ने और कठिन सशर्त तर्क लेने के लिए कठिन होता है जो एक स्थान से संबंधित होता है और इसे दो स्थानों में विभाजित करता है।

कई मामलों में जहां मैं {% switch %} (या एक {% if %}) उपयोगी हो सकता है, किसी का उपयोग न करने के लिए HTML को एक दृश्य में रखना आवश्यक है। यह एक बहुत बुरा पाप है और यही कारण है कि {% if %} पहले स्थान पर मौजूद है। {% switch %} कोई अलग नहीं है।

सौभाग्य से, Django एक्स्टेंसिबल है और कई लोगों ने स्विच लागू किया है। देखें:

Switch template tag

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

यह शानदार है! मुझे लगता है कि मेरा एकमात्र जोड़ा इसे बनाना होगा ताकि आप 'x के रूप में x के साथ' निर्दिष्ट कर सकें और इसे प्रत्येक मामले में y y पास कर दिया हो। लेकिन यह एक विशिष्ट आवश्यकता है। – Pureferret

41

Django 1.4 के रूप में, है {% elif %}:

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

जब 'साथ' टैग के साथ मिलकर हम स्विच के करीब सुंदर डांग प्राप्त कर सकते हैं। '{% के ​​साथ = ya.expensive.bro%} {% यदि कोई = 1%} एक {% elif a = 2%} दो {% else%} uhh {% endif%} {% endwith%}' .. यह सिर्फ एक स्पर्श बदसूरत है। –

संबंधित मुद्दे