टेम्प्लेट कोड के अंदर एक वैरिएबल का मान कैसे सेट करें?


216

कहो मेरे पास एक खाका है

<html>
<div>Hello {{name}}!</div>
</html>

इसका परीक्षण करते समय, इस टेम्पलेट को लागू करने वाले अजगर कोड को छूने के बिना चर के मूल्य को परिभाषित करना उपयोगी होगा। तो मैं कुछ इस तरह की तलाश में हूं

{% set name="World" %}     
<html>
<div>Hello {{name}}!</div>
</html>

क्या Django में ऐसा कुछ मौजूद है?

जवाबों:


327

आप withटेम्पलेट टैग का उपयोग कर सकते हैं ।

{% with name="World" %}     
<html>
<div>Hello {{name}}!</div>
</html>
{% endwith %}

35
लेकिन क्या आप चर के मान को बदल सकते हैं?
डेविड David वोंग

2
ऐसा लगता है कि आप एक कंटेनर की घोषणा नहीं कर सकते हैं (मैंने सूची और टपल की कोशिश की है) एक क्लॉज के साथ
व्लादिस्लाव इविनिशिन

यदि आपको एक सूची घोषित करने की आवश्यकता है, तो make_list का उपयोग करें। docs.djangoproject.com/en/1.9/ref/templates/builtins/#make-list
MrValdez

3
जिन्जा कहते हैं कि यह {% सेट मायवर = मूल्य%} है क्यों यह django में काम नहीं करता है?
Holms

3
@होल्म्स क्योंकि Django जिनजा का उपयोग नहीं करता है :-) docs.djangoproject.com/en/1.7/topics/templates
elimisteve

50

एक टेम्प्लेट टैग बनाएं:

एप्लिकेशन में एक templatetagsनिर्देशिका होनी चाहिए , जैसे कि उसी स्तर पर models.py, views.pyआदि। यदि यह पहले से मौजूद नहीं है, तो इसे बनाएं - __init__.pyनिर्देशिका पायथन पैकेज के रूप में माना जाता है यह सुनिश्चित करने के लिए फ़ाइल को मत भूलना ।

निम्नलिखित कोड के साथ टेम्प्लेटसेटैग्स डायरेक्टरी के define_action.pyअंदर एक फाइल बनाएं :

from django import template
register = template.Library()

@register.simple_tag
def define(val=None):
  return val

नोट: विकास सर्वर स्वचालित रूप से पुनः आरंभ नहीं करेगा। templatetagsमॉड्यूल जोड़ने के बाद , आपको टेम्प्लेट में टैग या फ़िल्टर का उपयोग करने से पहले अपने सर्वर को पुनरारंभ करना होगा।


फिर अपने टेम्पलेट में आप इस तरह से संदर्भ के लिए मान निर्दिष्ट कर सकते हैं:

{% load define_action %}
{% if item %}

   {% define "Edit" as action %}

{% else %}

   {% define "Create" as action %}

{% endif %}


Would you like to {{action}} this item?

2
मेरे मामले में लूप के बाद यह पुराना मूल्य देता है :(
होम्स

7
नवीनतम संस्करण में यह प्रतीत होता है कि आप असाइनमेंट_टैग के बजाय simple_tag का उपयोग कर सकते हैं (और यह मेरे लिए काम करता है)।
काथराइन ओसबोर्न

इस समाधान के साथ मुझे प्राप्त समस्या यह है कि यह प्रतीत होता है, कि आप मानों को ओवरराइड नहीं कर सकते।
जैकब जबालोस्की

यदि आप इस तकनीक का उपयोग सिर्फ मूल्य के बजाय सूची सेट करने के लिए करना चाहते हैं, तो इसे देखें: stackoverflow.com/a/34407158/2193235
msb

यदि आप एक पूर्णांक के रूप में चर सेट कर रहे हैं और आप इसे (उदाहरण के लिए) को बढ़ाने के लिए चाहते हैं, आप उपयोग करने की जरूरत है add: {% define counter|add:1 as counter %}। इसी तरह अन्य परिचालनों के लिए।
एमएसबी

35

एक वैकल्पिक तरीका जिसके लिए आपको "ब्लॉक" के साथ सब कुछ डालने की आवश्यकता नहीं है, एक कस्टम टैग बनाना है जो संदर्भ में एक नया चर जोड़ता है। जैसे की:

class SetVarNode(template.Node):
    def __init__(self, new_val, var_name):
        self.new_val = new_val
        self.var_name = var_name
    def render(self, context):
        context[self.var_name] = self.new_val
        return ''

import re
@register.tag
def setvar(parser,token):
    # This version uses a regular expression to parse tag contents.
    try:
        # Splitting by None == splitting by spaces.
        tag_name, arg = token.contents.split(None, 1)
    except ValueError:
        raise template.TemplateSyntaxError, "%r tag requires arguments" % token.contents.split()[0]
    m = re.search(r'(.*?) as (\w+)', arg)
    if not m:
        raise template.TemplateSyntaxError, "%r tag had invalid arguments" % tag_name
    new_val, var_name = m.groups()
    if not (new_val[0] == new_val[-1] and new_val[0] in ('"', "'")):
        raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name
    return SetVarNode(new_val[1:-1], var_name)

इससे आप अपने टेम्प्लेट में कुछ इस तरह लिख पाएंगे:

{% setvar "a string" as new_template_var %}

ध्यान दें कि इसमें से अधिकांश यहां से लिया गया था


संदर्भ में मौजूद अन्य चर के लिए चर प्रदान करने के बारे में कैसे? और एक अलग नोट पर: टेम्प्लेट को मनमाने ढंग से संदर्भ चर असाइन करने के लिए टेम्प्लेट की अनुमति देना अगर वे पहले से मौजूद हैं तो उनके सुरक्षा निहितार्थ हो सकते हैं। : मेरी राय में एक और अधिक समझदार दृष्टिकोण यह निर्दिष्ट करने के लिए प्रयास करने से पहले चर के लिए संदर्भ की जांच करने के होगा
soze

यदि context.get (self.var_name): उठाने SuspiciousOperation ( "टेम्पलेट पहले से ही संदर्भ में वर्तमान से असाइन चर करने का प्रयास")
soze

27

जॉन द्वारा वर्णित की तरह चालें हैं; हालाँकि, डिज़ाइन द्वारा Django की टेम्पलेट भाषा एक चर सेट करने का समर्थन नहीं करती है ( टेम्पलेट के लिए Django प्रलेखन में "दर्शन" बॉक्स देखें )।
इस वजह से, किसी भी चर बदलने के लिए सुझाया गया तरीका है पायथन कोड को छू के माध्यम से।


7
सूचक के लिए धन्यवाद। एक डिजाइनर के दृष्टिकोण से, कभी-कभी इसे डिज़ाइन करते समय किसी पृष्ठ के विभिन्न राज्यों का परीक्षण करने के लिए एक चर सेट करना आसान होता है। इस अभ्यास का सुझाव नहीं है कि एक चल रहे कोड में उपयोग किया जाए।
एलेक्सिस

2
"के साथ" टैग django1.0 में स्वीकार किया जाता है। तो ऐसा लगता है कि वे अंततः अपने दर्शन में संशोधन कर रहे हैं :)।
एवगेनी डेस

2
तथ्यों के रूप में, "के साथ" टैग सिर्फ उपनामों के लिए है। इसका प्रदर्शन (और पठनीयता पर भी) पर भारी प्रभाव पड़ सकता है, लेकिन यह वास्तव में पारंपरिक प्रोग्रामिंग शब्दों में परिवर्तनशील नहीं है।
लूट

12

इसके लिए सबसे अच्छा उपाय है कस्टम लिखना assignment_tag। यह समाधान withटैग का उपयोग करने से अधिक साफ है क्योंकि यह तर्क और स्टाइल के बीच एक बहुत स्पष्ट अलगाव को प्राप्त करता है।

टेम्पलेट टैग फ़ाइल (जैसे। appname/templatetags/hello_world.py) बनाकर प्रारंभ करें :

from django import template

register = template.Library()

@register.assignment_tag
def get_addressee():
    return "World"

अब आप get_addresseeअपने टेम्प्लेट में टेम्प्लेट टैग का उपयोग कर सकते हैं :

{% load hello_world %}

{% get_addressee as addressee %}

<html>
    <body>
        <h1>hello {{addressee}}</h1>
    </body>
</html>

3
नए Django संस्करणों का उपयोग करने वाले लोगों के लिए, इसे अब simple_tag कहा जाता है! यह जानने के लिए समय बचाएं कि "रजिस्टर .." आपके कोड में क्यों नहीं पहचाना गया है ...
काया

11

शायद defaultटेम्पलेट फ़िल्टर 2009 में वापस विकल्प नहीं था ...

<html>
<div>Hello {{name|default:"World"}}!</div>
</html>

मुझे कहना होगा कि यह वही है जो मैं देख रहा था! यह भी साथ इस्तेमाल किया जा सकता हो के साथ : {% with state=form.state.value|default:other_context_variable %}के बजाय other_context_variableहम भी किसी भी उपयोग कर सकते हैं 'string_value'और साथ ही
सौरव कुमार

लेकिन यह यह प्रिंट होगा, और मैं बाद में उपयोग के लिए सहेजने की जरूरत
Holms

4

यह सामान्य रूप से एक अच्छा विचार नहीं है। अजगर में सभी तर्क और प्रदर्शन के लिए टेम्पलेट को डेटा पास करें। टेम्पलेट यथासंभव सरल होनी चाहिए ताकि यह सुनिश्चित हो सके कि डिज़ाइन पर काम करने वाले तर्क के बारे में चिंता करने के बजाय डिज़ाइन पर ध्यान केंद्रित कर सकते हैं।

एक उदाहरण देने के लिए, यदि आपको किसी टेम्पलेट के भीतर कुछ व्युत्पन्न जानकारी की आवश्यकता है, तो इसे अजगर कोड में एक चर में प्राप्त करना बेहतर है और फिर इसे टेम्पलेट के साथ पास करें।


3

कथन के साथ प्रयोग करें ।

{% with total=business.employees.count %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}

मैं इस उत्तर में पहले पैराग्राफ में कोड का अर्थ नहीं लगा सकता । हो सकता है कि टेम्पलेट भाषा ने पुराने प्रारूप को हटा दिया हो।


2

अपने टेम्पलेट में आप ऐसा कर सकते हैं:

{% jump_link as name %}
{% for obj in name %}
    <div>{{obj.helo}} - {{obj.how}}</div>
{% endfor %}

अपने टेम्प्लेट-टैग में आप इस तरह एक टैग जोड़ सकते हैं:

@register.assignment_tag
def jump_link():
    listArr = []
    for i in range(5):
        listArr.append({"helo" : i,"how" : i})
    return listArr
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.