Как использовать jinja2 в качестве движка шаблонов в Django 1.8

Я искал, как использовать jinja2 в django 1.8, но нет полного источника для использования django с jinja2. Мне было интересно, знаете ли вы, ребята, процесс использования jinja2 в django. Я просмотрел официальную документацию и посмотрел на следующий вопрос: Как настроить django 1.8 для использования jinja2?

но никто из них не объясняет, как правильно использовать jinja2. Я только начал использовать django и не знаю всех языков в документах. Буду очень признателен за помощь.

5 ответов

Фрист вы должны установить jinja2:

$ pip install Jinja2

Затем измените ваш TEMPLATES список в файле settings.py, чтобы содержать jinja2BACKEND:

TEMPLATES = [

    {
        'BACKEND': 'django.template.backends.jinja2.Jinja2',
        'DIRS': [os.path.join(BASE_DIR, 'templates/jinja2')],
        'APP_DIRS': True,
        'OPTIONS': {'environment': 'myproject.jinja2.Environment',}, 
    },
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        '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',
           ],
        },
    },
]

где templates/jinja2 каталог с файлами шаблонов jinja2

И в вашем файле views.py:

from __future__ import absolute_import  # Python 2 only
from jinja2 import Environment
from django.contrib.staticfiles.storage import staticfiles_storage
from django.urls import reverse

def environment(**options):
    env = Environment(**options)
    env.globals.update({
       'static': staticfiles_storage.url,
       'url': reverse,
    })
    return env

Это делает static а также url доступны в ваших шаблонах Jinja2.

PS Подробнее читайте в этой статье.

Мне потребовалось некоторое время, чтобы все выяснить, ответы здесь были не так уж полезны.

Ответ Дору наиболее близок к истине, но неполон.

Как использовать дзиндзя в качестве языка шаблонов:

1. Создайте файл jinja2.py в папке вашего проекта. Это необходимо для изменения среды jinja2 по умолчанию (в нашем случае, передавая некоторые дополнительные глобальные переменные).

место нахождения: {root}/main/jinja2.py:

from __future__ import absolute_import  # Python 2 only
from jinja2 import Environment
from django.contrib.staticfiles.storage import staticfiles_storage
from django.core.urlresolvers import reverse

def environment(**options):
    env = Environment(**options)
    env.globals.update({
       'static': staticfiles_storage.url,
       'url': reverse,
    })
    return env

2. Добавьте бэкенд jinja2 в файл настроек проекта django, включая нашу модифицированную среду.

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.jinja2.Jinja2',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'environment': "main.jinja2.environment",
        },
    },
    ...
]

3. Теперь вам больше не нужно импортировать jinja2 куда-либо, в ваших представлениях вы будете использовать шаблоны jinja через django так же, как шаблоны django:

from django.shortcuts import render

def index(request, **kwargs):
    return render(request, "index.html.j2", {'title': 'MyTitle', 'text': "MyText"})

И наконец, если для APP_DIRS установлено значение True, jinja будет искать шаблоны во всех установленных приложениях. jinja2 каталоги. (в отличие от DTL, который ищет templates папка). Если вы хотите изменить это поведение или хотите внести некоторые дополнительные изменения, такие как сопоставление расширений, фильтрация или глобальные переменные, вам стоит взглянуть на расширение django-jinja.

Вы также можете предоставить дополнительные каталоги для поиска шаблонов через TEMPLATES['DIRS'] опция настроек.

Смешанные Django и Jinja2 Шаблон: Среда: Django 1.8 + Jinja2.

У меня есть несколько устаревших шаблонов Django, и их не так просто переписать сразу в Jinja2, поэтому добавьте этот пользовательский {% jinja_include "some_template.jinja" %} тег к my_custom_tags.py:

from django.template.loader import get_template
from django import template
register = template.Library()

@register.simple_tag(takes_context=True)
def jinja_include(context, filename):
    template = get_template(filename)
    return template.render(context.flatten())

Назовите это так из вашего шаблона Django:

{% load my_custom_tags %}
{% jinja_include "some_template.jinja" %}

Обновление для Django 3+: Real Life config Jinja2 3.0.X +

<имя_проекта> /settings.py

      TEMPLATES = [
{
    "BACKEND": "django.template.backends.jinja2.Jinja2",
    "DIRS": [os.path.join(BASE_DIR, "ui", "templates")], # You can add a subdirectory like /jinja2 if you don't want Jinja2 to be default. But for consistency I do not recommand
    "APP_DIRS": True,
    "OPTIONS": {
        'environment': ".".join([os.path.basename(BASE_DIR), 'jinja2.environment']),
        "context_processors": [
            "django.contrib.auth.context_processors.auth",
            "django.template.context_processors.debug",
            "django.template.context_processors.i18n",
            "django.template.context_processors.media",
            "django.template.context_processors.static",
            "django.template.context_processors.tz",
            "django.contrib.messages.context_processors.messages",
        ],
    }
},
{
    "BACKEND": "django.template.backends.django.DjangoTemplates",
    "DIRS": [],
    "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",
        ],
    },
},]

<имя_проекта> / <имя_проекта> /jinja2.py

      import inspect
import logging

from django.contrib import messages
from jinja2 import Environment, pass_context
from django.contrib.staticfiles.storage import staticfiles_storage
from django.urls import reverse

import ui.templatetags.extras as extras_filters
from crispy_forms.utils import render_crispy_form

logger = logging.getLogger(__name__)

# /!\ This this how you make csrf token generated by crispy properly injected
@pass_context 
def crispy(context, form):
    return render_crispy_form(form, context=context)

def environment(**options):
    logger.debug("Jinja2 environment loading")
    env = Environment(**options)
    env.globals.update({
       "get_messages": messages.get_messages,
       "static": staticfiles_storage.url,
       "crispy": crispy,  # this line is different
       "url": reverse,
   })
   # Bonus, get your django custom templatetag, backward compatible with Django Template
   env.filters.update(dict(inspect.getmembers(extras_filters, inspect.isfunction)))
   return env

/ui/views.py

      import logging

from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Submit


logger = logging.getLogger(__name__)

class AddRemoteServerForm(forms.Form):
    name = forms.CharField(max_length=20, min_length=3)
    url = forms.CharField(max_length=200)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.layout = Layout(
        'name',
        'url',
        Submit('submit', 'Associate Server')
    )

<имя_проекта> /ui/views.py

      def add_remote_server(request):
if request.method == 'POST':
    form = AddRemoteServerForm(request.POST)
    logger.debug(form.data.dict())
    logger.debug("Form valid ? %s " % form.is_valid())
    if form.is_valid():
        d = form.data.dict()
        # TODO: Implmenent your business logic
        return redirect('/remote_servers/')
else:
    form = AddRemoteServerForm()
context = {'form': form}
return render(request, 'form.html', context)

<имя_проекта> /ui/templates/form.html

      {% extends "base.html" %}
{% block extraappendjavascript %}
{% endblock %}
{% block content %}
<div class="container">
    <div class="card">
        <div class="card-body">
            {{ crispy(form) }}
        </div>

    </div>
</div>
{% endblock %}

<имя_проекта> /ui/templatetags/extras.py # Бонус, к сведению

      import logging
import os
from datetime import datetime, timedelta

from django.utils.safestring import mark_safe
from django.template import Library

import json


register = Library()

logger = logging.getLogger(__name__)
@register.filter(is_safe=True)
def js(obj):
    try:
        return mark_safe(json.dumps(obj))
    except Exception:
        return "{}"

С веб-сайта Django (пожалуйста, посмотрите на это для дальнейшего руководства) в settings.py:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            # ... some options here ...
        },
    },
]

BACKEND - это пунктирный путь Python к классу шаблонизатора, реализующему шаблонный API-интерфейс Django. Встроенными бэкэндами являются django.template.backends.django.DjangoTemplates и django.template.backends.jinja2.Jinja2.

В основном выясните, где в вашем файле settings.py есть переменная TEMPLATES, и установите бэкэнд (или убедитесь, что бэкэнд) похож на приведенный выше (поскольку Jinga встроен). Если все не удается, замените django.template.backends... с django.template.backends.jinja2.Jinja2 (хотя я не думаю, что это необходимо).

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