खोज…


कस्टम फ़िल्टर

फ़िल्टर आपको किसी फ़ंक्शन को वैरिएबल पर लागू करने की अनुमति देता है। इस फ़ंक्शन में 0 या 1 तर्क हो सकता है। यहाँ वाक्य रचना है:

{{ variable|filter_name }} 
{{ variable|filter_name:argument }}

फिल्टर जंजीर हो सकते हैं तो यह पूरी तरह से मान्य है:

{{ variable|filter_name:argument|another_filter }}

यदि उपरोक्त पंक्ति का अनुवाद अजगर के लिए किया जाता है तो वह कुछ इस तरह का होगा:

print(another_filter(filter_name(variable, argument)))

इस उदाहरण में, हम एक कस्टम फ़िल्टर verbose_name जो एक मॉडल (उदाहरण या वर्ग) या QuerySet पर लागू होता है। तर्क पर सेट है यह एक मॉडल, या उसके वर्बोज़ नाम बहुवचन की वर्बोज़ नाम वापस आ जाएगी True

@register.filter
def verbose_name(model, plural=False):
    """Return the verbose name of a model.
    `model` can be either:
      - a Model class
      - a Model instance
      - a QuerySet
      - any object refering to a model through a `model` attribute.

    Usage:
      - Get the verbose name of an object
          {{ object|verbose_name }}
      - Get the plural verbose name of an object from a QuerySet
          {{ objects_list|verbose_name:True }}
    """
    if not hasattr(model, '_meta'):
        # handle the case of a QuerySet (among others)
        model = model.model
    opts = model._meta
    if plural:
        return opts.verbose_name_plural
    else:
        return opts.verbose_name

सरल टैग

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

यहाँ एक बेकार टैग है जो हमारे उदाहरण का वर्णन करेगा:

{% useless 3 foo 'hello world' foo=True bar=baz.hello|capfirst %}

निम्नलिखित की तरह foo और baz को संदर्भ चर होने दें:

{'foo': "HELLO", 'baz': {'hello': "world"}}

कहो कि हम इस तरह से प्रस्तुत करने के लिए यह बहुत बेकार टैग चाहते हैं:

HELLO;hello world;bar:World;foo:True<br/>
HELLO;hello world;bar:World;foo:True<br/>
HELLO;hello world;bar:World;foo:True<br/>

तर्कों का प्रकार 3 बार दोहराया गया (3 पहला तर्क है)।

यहाँ टैग कार्यान्वयन क्या हो सकता है:

from django.utils.html import format_html_join

@register.simple_tag
def useless(repeat, *args, **kwargs):
    output = ';'.join(args + ['{}:{}'.format(*item) for item in kwargs.items()])
    outputs = [output] * repeat
    return format_html_join('\n', '{}<br/>', ((e,) for e in outputs))

format_html_join <br/> को सुरक्षित HTML के रूप में चिह्नित करने की अनुमति देता है, लेकिन outputs की सामग्री नहीं।

नोड का उपयोग कर उन्नत कस्टम टैग

कभी-कभी आप जो करना चाहते हैं वह सिर्फ एक filter या एक simple_tag लिए बहुत जटिल simple_tag । यह कैसे आप एक संकलन समारोह और एक रेंडर बनाने के लिए की आवश्यकता होगी।

इस उदाहरण में हम निम्नलिखित सिंटैक्स के साथ एक टेम्प्लेट टैग verbose_name :

उदाहरण विवरण
{% verbose_name obj %} एक मॉडल का क्रिया नाम
{% verbose_name obj 'status' %} फ़ील्ड का नाम "स्थिति"
{% verbose_name obj plural %} एक मॉडल का वर्बोस नाम बहुवचन
{% verbose_name obj plural capfirst %} एक मॉडल के बड़े आकार वाली वर्बोज़ नाम बहुवचन
{% verbose_name obj 'foo' capfirst %} किसी फ़ील्ड का कैपिटलाइज़्ड वर्बोज़ नाम
{% verbose_name obj field_name %} एक चर से क्षेत्र का नाम
{% verbose_name obj 'foo'|add:'_bar' %} किसी फ़ील्ड के शब्द का नाम "foo_bar"

एक साधारण टैग के साथ हम ऐसा क्यों नहीं कर सकते इसका कारण यह है कि plural और capfirst न तो चर हैं और न ही तार, वे "कीवर्ड" हैं। हम स्पष्ट रूप से उन्हें 'plural' और 'capfirst' रूप में पारित करने का निर्णय ले सकते हैं, लेकिन यह इन नामों वाले क्षेत्रों के साथ संघर्ष कर सकता है। क्या " {% verbose_name obj 'plural' %} अर्थ" obj बहुवचन नाम बहुवचन "या" obj.plural नाम "होगा?

पहले संकलन समारोह बनाएँ:

@register.tag(name='verbose_name')
def do_verbose_name(parser, token):
    """
    - parser: the Parser object. We will use it to parse tokens into
              nodes such as variables, strings, ...
    - token: the Token object. We will use it to iterate each token
             of the template tag.
    """
    # Split tokens within spaces (except spaces inside quotes)
    tokens = token.split_contents()
    tag_name = tokens[0]
    try:
        # each token is a string so we need to parse it to get the actual
        # variable instead of the variable name as a string.
        model = parser.compile_filter(tokens[1])
    except IndexError:
        raise TemplateSyntaxError(
            "'{}' tag requires at least 1 argument.".format(tag_name))

    field_name = None
    flags = {
        'plural': False,
        'capfirst': False,
    }

    bits = tokens[2:]
    for bit in bits:
        if bit in flags.keys():
            # here we don't need `parser.compile_filter` because we expect
            # 'plural' and 'capfirst' flags to be actual strings.
            if flags[bit]:
                raise TemplateSyntaxError(
                    "'{}' tag only accept one occurrence of '{}' flag".format(
                        tag_name, bit)
                )
            flags[bit] = True
            continue
        if field_name:
            raise TemplateSyntaxError((
                "'{}' tag only accept one field name at most. {} is the second "
                "field name encountered."
            ).format(tag_name, bit)
        field_name = parser.compile_filter(bit)

    # VerboseNameNode is our renderer which code is given right below
    return VerboseNameNode(model, field_name, **flags)

और अब रेंडर:

class VerboseNameNode(Node):

    def __init__(self, model, field_name=None, **flags):
        self.model = model
        self.field_name = field_name
        self.plural = flags.get('plural', False)
        self.capfirst = flags.get('capfirst', False)

    def get_field_verbose_name(self):
        if self.plural:
            raise ValueError("Plural is not supported for fields verbose name.")
        return self.model._meta.get_field(self.field_name).verbose_name

    def get_model_verbose_name(self):
       if self.plural:
           return self.model._meta.verbose_name_plural
       else:
           return self.model._meta.verbose_name

    def render(self, context):
        """This is the main function, it will be called to render the tag.
        As you can see it takes context, but we don't need it here.
        For instance, an advanced version of this template tag could look for an
        `object` or `object_list` in the context if `self.model` is not provided.
        """
        if self.field_name:
            verbose_name = self.get_field_verbose_name()
        else:
            verbose_name = self.get_model_verbose_name()
        if self.capfirst:
            verbose_name = verbose_name.capitalize()
        return verbose_name


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow