django шаблон наследования и assingment_tag

Я хочу написать тег назначения и добавить в app/templatetags/app_extras.py

@register.assignment_tag
def get_obj (objid) :
    return get_object_or_404(MyModel, id=objid)

и в шаблоне

{% extends "index.html" %}

{% load app_extras %}
{% get_obj 1 as obj %}

{% block title %}{{ obj.name }}{% endblock %}
{% block content %}{{ obj.description }}{% endblock %}

переменная obj не видно в блоках.

Если я напишу

...
{% load app_extras %}

{% block title %}{% get_obj 1 as obj %}{{ obj.name }}{% endblock %}
...

obj определен в блоке, но не определен в блоке "content".

Как сделать переменную доступной в блоках?

1 ответ

Решение

Здесь есть две проблемы. Первый - когда вы находитесь в шаблоне второго уровня (который "расширяет" базовый), контент за пределами {% block %} не обрабатывается. Так вот почему у вас нет назначенного значения в блоках. Это никогда не было назначено на самом деле.

Вторая проблема заключается в том, что контекст в блоке специфичен и доступен только в блоке, а не между блоками. Чтобы сделать его доступным в нескольких блоках - вы должны поделиться им. Вот как context может быть использован в assignment_tag:

@register.assignment_tag(takes_context=True)
def get_obj (context, objid) :
    context.obj = get_object_or_404(MyModel, id=objid)
    return context.obj

Используя этот тег, вы можете назначить переменную в вашем первом блоке:

{% block title %}{% get_obj 1 as obj %}{{ obj.name }}{% endblock %}

а затем использовать его из контекста в следующем блоке:

{% block content %}{{ obj.name }}{% endblock %}

ИМХО, это не лучший способ сделать что-то, хотя это работает. Проблема здесь в том, что шаблон изменяет / перезаписывает контекст и может привести к нежелательному поведению в некоторых случаях.

Другие вопросы по тегам