Как использовать 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, чтобы содержать jinja2
BACKEND
:
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
(хотя я не думаю, что это необходимо).