Переопределить существующие шаблоны шаблонов Django

Можно ли переопределить существующий тег шаблона Django или необходимо настроить файл шаблона и создать новый тег шаблона?

Ответ 1

Да.

Поскольку django - это в основном библиотека python (как и все в python), вы можете переписать все, что захотите.

Непонятно, что именно вы хотели бы сделать, но на самом деле довольно легко загрузить свой шаблон templatetag, документы довольно ясны: https://docs.djangoproject.com/en/dev/howto/custom-template-tags/#writing-custom-template-tags

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

MyApp/templatetags/my_custom_tags.py(должен иметь __init__.py в этом каталоге)

from django import template
register = template.Library()

class CustomTag(template.Node):
    def render(self, context):
        context['my_custom_tag_context'] = "this is my custom tag, yeah"
        return ''

@register.tag(name='get_custom_tag')
def get_custom_tag(parser, token):
    return CustomTag()

Использование в вашем шаблоне выглядит следующим образом:

{% load my_custom_tags %}
{% get_custom_tag %}
{{my_custom_tag_context}}

Вероятно, вы хотите проанализировать token, и вам, вероятно, понадобится какой-то __init__ в классе, но он показывает, насколько он базовый.


Вы можете просматривать существующие шаблоны templatetags по умолчанию, реплицировать и изменять их до вашего сердечного контента.

Там действительно есть отличный материал: https://github.com/django/django/blob/master/django/template/defaulttags.py

Ответ 2

Я искал тот же ответ, поэтому решил, что поделюсь своим решением здесь. Я хотел бы переопределить тег шаблона url по умолчанию в django, не используя специальный тег шаблона и загружая его в каждый файл шаблона.

Цель заключалась в том, чтобы заменить %20 ​​(пробелы) на + (плюсы). Вот что я придумал...

В init.py

from django.template.defaulttags import URLNode

old_render = URLNode.render
def new_render(cls, context):
  """ Override existing url method to use pluses instead of spaces
  """
  return old_render(cls, context).replace("%20", "+")
URLNode.render = new_render

Эта страница была полезной https://github.com/django/django/blob/master/django/template/defaulttags.py

Ответ 3

Я предполагаю, что "существующий шаблон шаблона Django" означает тег в другом приложении.

Создайте templatetags/tagfile.py, который регистрирует тег с тем же именем. Убедитесь, что tagfile - это то же имя, что шаблон загружается с помощью {% load tagfile %} для получения исходного тега.

Кроме того, убедитесь, что ваше приложение указано после исходного приложения в INSTALLED_APPS.

Ответ 4

Если вы не хотите зависеть от порядка вашего приложения в файле settings.py INSTALLED_APPS, вы можете попробовать следующее:

Создайте функцию/класс шаблона тега как обычно. Скажем, вы хотите переопределить otherapp_tags.current_time шаблона с именем otherapp_tags.current_time из приложения с именем other_app. Сначала создайте собственную версию этой функции/класса:

def my_current_time(format_string):
    return datetime.datetime.now().strftime(format_string)

затем, вместо регистрации этой функции/класса в пространстве имен ВАШИХ приложений, исправьте существующую функцию из другого приложения:

from other_app.templatetags import otherapp_tags

otherapp_tags.register.tags['current_time'] = my_current_time

Обычно вы должны делать это внутри вашего метода AppConfig ready().

Ответ 5

Я уверен, что вы просите полное переопределение тега templatetag django.

Краткий ответ - Yes, вы можете переопределить существующий templatetag.

Вот как это сделать:

  • Вы должны включить каталог шаблонов в settings:
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'your_app/templates')],
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                    'django.template.context_processors.static',
                ],
            },
        },
    ]
  • Вы должны включить приложение, для которого вы хотите переопределить тег templatetag, в INSTALLED_APPS:
INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'your_app_name',
        ...
    ]

Важный момент - иметь приложение после django-приложений!

Это связано с тем, как работает Django. Мы получим право на использование этого.

  • Теперь создайте папку внутри вашего приложения с именем templatetags. Важно иметь файл __init__.py внутри __init__.py - templatetags, чтобы django мог понять, что это пакет python !:

your_app_name/templatetags/__init__.py.

  • Создайте templatetag вы хотите переопределить. В этом примере я буду использовать тег admin_list.py.

В этом случае он должен быть размещен так:

your_app_name/templatetags/admin_list.py

  • Теперь скопируйте весь контент admin_list.py (ОЧЕНЬ ВАЖНО!) Из django.contrib.admin.templatetags.admin_list.py и измените все, что вы хотите.

Важно иметь весь контент django admin admin_list.py а не только кусок кода, иначе он не будет работать!


Как это работает: Django ищет в вашем приложении папку templatetags и использует внутри нее теги шаблона. Он размещает ваши шаблонные теги после admin's, и вкратце - он переопределяет их, поскольку они помещаются после django.admin в INSTALLED_APPS.

Не забудь:

  • ./manage.py collectstatic
  • установить DEBUG = False в производстве

Я уже проверил это для переопределения функции result_list(cl), и это работает.

Надеюсь, это поможет.