Frage

Ich mache so etwas wie:

{% extends 'base.html' %}
{% url myapp.views.dashboard object as object_url %}
{% block sidebar %}
... {{ object_url }} ...
{% endblock %}
{% block content %}
... {{ object_url }} ...
{% endblock %}

Django -Dokumentation sagt, dass URL -Templatetag eine Variable im Kontext definieren kann, aber ich bekomme keinen Wert für object_url in den folgenden Blöcken.

Wenn ich das URL -Templatetag zu Beginn jedes Blocks einsetze, funktioniert es, aber ich möchte mich nicht "wiederholen".

Kennt jemand eine bessere Lösung?

War es hilfreich?

Lösung

Wenn die URL spezifisch ist, können Sie die URL aus Ihrer Ansicht übergeben. Wenn die URL in Ihren Vorlagen wirklich global sein muss, können Sie sie einsetzen ein Kontextprozessor:

def object_url(request):
    return {'object_url': reverse('myapp.views.dashboard')}

Andere Tipps

Es sieht so aus, als ob dies zuvor beantwortet wurde, aber es gibt eine Alternative. Es ist eine Sache, einen Kontextprozessor zu verwenden, um etwas zu verfolgen, das von außerhalb der Vorlage definiert ist, aber manchmal möchten Sie die Häufigkeit zählen, die zwei Loops durchlaufen oder so etwas. Es geht auch anders:

class GlobalVariable(object):
    def __init__(self, varname, varval):
        self.varname = varname
        self.varval = varval

    def name(self):
        return self.varname

    def value(self):
        return self.varval

    def set(self, newval):
        self.varval = newval


class GlobalVariableSetNode(template.Node):
    def __init__(self, varname, varval):
        self.varname = varname
        self.varval = varval

    def render(self, context):
        gv = context.get(self.varname, None)
        if gv:
            gv.set(self.varval)
        else:
            gv = context[self.varname] = GlobalVariable(
                self.varname, self.varval)
        return ''


def setglobal(parser, token):
    try:
        tag_name, varname, varval = token.contents.split(None, 2)
    except ValueError:
        raise template.TemplateSyntaxError(
            "%r tag requires 2 arguments" % token.contents.split()[0])
    return GlobalVariableSetNode(varname, varval)


register.tag('setglobal', setglobal)


class GlobalVariableGetNode(template.Node):
    def __init__(self, varname):
        self.varname = varname

    def render(self, context):
        try:
            return context[self.varname].value()
        except AttributeError:
            return ''


def getglobal(parser, token):
    try:
        tag_name, varname = token.contents.split(None, 1)
    except ValueError:
        raise template.TemplateSyntaxError(
            "%r tag requires arguments" % token.contents.split()[0])
    return GlobalVariableGetNode(varname)


register.tag('getglobal', getglobal)


class GlobalVariableIncrementNode(template.Node):
    def __init__(self, varname):
        self.varname = varname

    def render(self, context):
        gv = context.get(self.varname, None)
        if gv is None:
            return ''
        gv.set(int(gv.value()) + 1)
        return ''


def incrementglobal(parser, token):
    try:
        tag_name, varname = token.contents.split(None, 1)
    except ValueError:
        raise template.TemplateSyntaxError(
            "%r tag requires arguments" % token.contents.split()[0])
    return GlobalVariableIncrementNode(varname)


register.tag('incrementglobal', incrementglobal)

Auf diese Weise können Sie es in einer solchen Vorlage verwenden:

{% setglobal ii 0 %}
...
{% for ... %}
  {% incrementglobal ii %}
  current={% getglobal ii %}
{% endfor %}
...
{% for ... %}
  {% incrementglobal ii %}
  current={% getglobal ii %}
{% endfor %}
...
total of 2 loops={% getglobal ii %}
...
{% setglobal ii 0 %}
...
do something else now that {% getglobal ii %} is back to 0

Sie können ein benutzerdefiniertes Vorlagen -Tag schreiben:

@register.simple_tag(takes_context=True)
def set_global_context(context, key, value):
    """
    Sets a value to the global template context, so it can
    be accessible across blocks.

    Note that the block where the global context variable is set must appear
    before the other blocks using the variable IN THE BASE TEMPLATE.  The order
    of the blocks in the extending template is not important. 

    Usage::
        {% extends 'base.html' %}

        {% block first %}
            {% set_global_context 'foo' 'bar' %}
        {% endblock %}

        {% block second %}
            {{ foo }}
        {% endblock %}
    """
    context.dicts[0][key] = value
    return ''

Nun, das ist eine irgendwie missbräuchliche Vorlageerbranz, aber Sie könnten verwenden {{block.super}} Object_url in Ihre Blöcke einfügen.

Mit anderen Worten, in Ihrer Vorlage mit mittlerer Ebene:

{% block sidebar %}{{ object_url }}{% endblock %}
{% block content %}{{ object_url }}{% endblock %}

Und dann verwenden Sie in Ihren Blockvorlagen:

{% block sidebar %}
... {{ block.super }}...
{% endblock %}

Es ist keine großartige Idee, weil es Sie daran hindert, etwas anderes zu setzen {{ object_url }} in deinen Block ... aber es funktioniert. Sag einfach niemandem, dass du es von mir hast!

In jeder ererbten Vorlage wird keine Code außerhalb der Blöcke neu definitionen ausgeführt. In Ihrem Beispiel müssen Sie also anrufen {% url %} Tag in jedem Block oder verwenden Sie den Kontextprozessor zum Einstellen der "globalen" Variablen.

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