문제

나는 다음과 같은 일을하고 있습니다.

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

Django 문서화는 URL TemplateTag가 컨텍스트에서 변수를 정의 할 수 있지만 object_url 다음 블록에서.

각 블록의 시작 부분에 URL 템플릿 태그를 넣으면 작동하지만 "자신을 반복하고 싶지 않습니다".

누구든지 더 나은 솔루션을 알고 있습니까?

도움이 되었습니까?

해결책

URL이 뷰가 특정 인 경우 뷰에서 URL을 전달할 수 있습니다. 템플릿에서 URL이 진정으로 글로벌이어야하는 경우 컨텍스트 프로세서 :

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

다른 팁

이것이 전에 답변 된 것 같습니다. 그러나 대안이 있습니다. 컨텍스트 프로세서를 사용하여 템플릿 외부에서 정의 된 것을 추적하는 것이 한 가지이지만 때로는 두 개의 루프가 겪는 횟수 또는 그와 비슷한 시간을 계산하려고합니다. 다른 방법이 있습니다 :

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)

이렇게하면 다음과 같은 템플릿에서 사용할 수 있습니다.

{% 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

사용자 정의 템플릿 태그를 작성할 수 있습니다.

@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 ''

글쎄, 이것은 템플릿 상속을 학대하지만 사용할 수 있습니다. {{block.super}} Object_url을 블록에 넣습니다.

다시 말해, 중간 수준의 템플릿에서 :

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

그런 다음 블록 템플릿에서 사용합니다.

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

그것은 당신이 그 외에 아무것도 넣지 못하도록하지 않기 때문에 좋은 생각이 아닙니다. {{ object_url }} 블록에 ...하지만 작동합니다. 당신이 나에게서 얻은 사람에게 말하지 마십시오!

상속 된 모든 템플릿에서 모든 코드 외부 블록 재정의는 실행되지 않습니다. 그래서 당신의 예에서 당신은 전화해야합니다 {% url %} "Global"변수를 설정하기 위해 각 블록 내부의 태그 또는 컨텍스트 프로세서를 사용하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top