Привет. Не давно была задача реализовать боковое меню со списком каталогов; что бы его можно было вставить в любое место и в любую страницу!
Проблема заключалась в том что список большой и для того что бы он не нагружал сервак я его закэшировал, но тут не буду указывать как закэшировал так как писать придется долго...
В общем буду описывать все по порядку!
Начнем с создания шаблонного тега! для того что бы его реализовать! я создал папку пакета:
назвать его можно как хотите но я его назвал его: context_processors
далее создал файл : right_menu.py
в котором будет реализована вся логика шаблонного тега.
from products.models import Category from django.core.cache import cache from django.db.models.aggregates import Count from django import template #нужен для регистрации шаблонного тега register = template.Library() #тут мы присваем значение @register.inclusion_tag('includes/right_menu.html') #декоратор для регистрации шаблона для подключения (я его указал в папке templates где находится base.html def get_right_school_menu(request): context = {} сategory_menu = cache.get('left_сategory_menu_' + request.LANGUAGE_CODE) #так как у меня мультиязычность стоит я сделал так. Оставлю для примера context['categorys'] = Category.objects.all() return context
далее в settings.py подключаем шаблонный тег
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.template.context_processors.i18n', 'django.contrib.messages.context_processors.messages', 'context_processors.right_menu.get_right_school_menu', # как видете тут я его подключил ], }, }, ]
в самом шаблоне right_menu.html
{% load static %} {% load i18n %} <ul> {% for i in categorys %} <li>{{ i.name }}</li> {% endfor %} </ul>
Добрый день!
Я добавил разделитель контента в статье, чтобы скрыть под катом основной содержание статьи. Спасибо за материал.
У меня есть вопрос, а почему не использовали просто папку templatetags для этого, например как здесь ?
Вы же здесь по сути написали middleware. Если таких inclusion tag будет очень много, то придётся каждый записывать в context processors.
Впрочем вы ответили на один из моих вопросов, как избавиться от подключения модуля, которым я задавался. Но минус по-моему в том, что потом придётся всё записывать в context_processors ....
так ты там тоже используешь теги! только симпл упращенный тег! только в твоем случает ты не подгружаешь шаблон! а так суть одна! но в моем случае я просто вывожу через инклуде ) он хорош для менюшек! Я так считаю ))
Согласен, что для менюшек хороши, я много чего на них сделал уже
Кстати, самого примере применения get_right_school_menu нет.
Как именно он выглядит в шаблоне?
Так?
inclusion tag делается точно так же в templatetags, вот например
применение в шаблоне будет таким
Просто у меня на сайте сейчас используется более 35-ти inclusion_tag, я бы свихнулся каждый прописывать в context_processros. Да и минус такого подхода в том, что каждый запрос обрабатывается всеми middleware вне зависимости, используется он или нет. То есть всё равно будет искаться тот метод, который ты используешь в шаблонах, даже если он не был там задействован. То есть, если тег не используется, то middleware работает вхолостую, тогда как templatetags будет подгружаться тогда, когда он действительно нужен.
нет!
будет так:
просто инклудишь шаблон где тебе он нужен и все!
Понятно, тогда это статья не о применении тега, а о написании context processor.
Видишь ли, тег include работает независимо от того, напишешь ли ты это
или нет
Тег include не смотрит на то, зарегистрирован ли шаблон в качестве имени или нет. И каждый раз при его вызове он ищет в каталогах данный шаблон.
То есть, если ты удалишь эти две строки, то ровным счётом ничего не изменится.
inclusion_tag, как я его написал в этом комментарии , служит именно для кеширования шаблона, чтобы не искать его каждый раз по каталогам, а ты его всё равно ищешь, то есть те две строки написаны впустую.
А context proccessor я понимаю почему там написан, как раз, чтобы генерить все эти категории вне зависимости от страницы, на которой находится пользователь. Но реально, отвечаю, те две строки лишние и работают вхолостую, их можно удалить и ровным счётом ничего не изменится.
то есть ты предлагаешь рендерить на прямую?
нет, я предлагаю сделать так. В каталоге приложения добавляешь каталог templatetags , а внутри него два файла, init .py и файл с названием приложения. Будет выглядеть так
то есть структура app будет такая
А далее добавляешь в файл с названием приложения свой inclusion_tag следующим образом
А потом в шаблоне вызываешь
Твой context processor добавит в контекст всё необходимое, а настройка takes_context=True позволит тегу его захватить.
Преимущество в данном случае будет в том, что шаблон будет реально закеширован и django не будет искать его при каждом рендеринге
а в settings тогда его нужно убрать! верно я понимаю?!
нет, в твоём случае он остается, это штука добавляет в контекст category при каждой обработке запроса.
Впрочем, если переписать так
То тогда да, можно и удалить из settings, тогда context processor тебе и вовсе не нужен
is not a registered tag library. Must be one of:
какая версия django?
Ну и структура каталогов и файлов, как написал выше, а также перезапустить инстанс джанги, если Debug=False, то автоматически не подхватывается без перезапуска
Django 2.1
пришлось зарегать его в
Странно конечно, что потребовалось добавлять каталог в libraries.
Ты добавил файл __init__.py в каталог templatetags? Чтобы получилась следующая структура
да. не помогло. наверное изза того что джанго 2
у меня тоже Django 2, не в этом дело, скорее всего в настройках ещё что-то пропущено, не знаю, мне всегда хватало того, что я указал уже выше.
Видимо я не обращал внимание на это
Шаблонные теги здесь совсем не причём. Уберите строки с template.Library, измените название на что то типа "одна из возможных реализаций бокового меню" и будет статья о контекстных процессорах в django для самых начинающих.