我一直在寻找如何在 django 1.8 中使用 jinja2,但是没有将 django 与 jinja2 一起使用的完整源代码。我想知道你们是否知道在 django 中使用 jinja2 的过程。我查看了官方文档,并查看了以下问题:How to setup django 1.8 to use jinja2?
但是他们都没有清楚地解释如何以组合方式使用 jinja2。我刚刚开始使用 django,不知道文档中的所有行话。我非常感谢您的帮助。
首先你必须安装
jinja2
:
$ pip install Jinja2
然后修改
settings.py中的
TEMPLATES
列表以包含 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 模板中可用。
P.S.欲了解更多详情,请参阅本文。
我花了相当长的时间才弄清楚一切,这里的答案并不是那么有帮助。
doru 的答案最接近事实,但并不完整。
如何使用 jinja 作为模板语言:
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,在你的视图中,你将通过django使用jinja模板,就像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
目录中搜索模板。 (与搜索 templates
文件夹的 DTL 不同)。如果你想改变这种行为,或者想要一些额外的调整,比如扩展匹配、过滤或全局变量,你应该看看 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+ 更新:现实生活配置 Jinja2 3.0.X +
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",
],
},
},]
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')
)
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)
{% extends "base.html" %}
{% block extraappendjavascript %}
{% endblock %}
{% block content %}
<div class="container">
<div class="card">
<div class="card-body">
{{ crispy(form) }}
</div>
</div>
</div>
{% endblock %}
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 是实现 Django 模板后端 API 的模板引擎类的点分 Python 路径。内置后端是 django.template.backends.django.DjangoTemplates 和 django.template.backends.jinja2.Jinja2。
基本上找出你的settings.py文件中哪里有一个TEMPLATES变量并设置后端(或确保后端)与上面的类似(因为Jinga是内置的)。如果全部失败,请将
django.template.backends...
替换为 django.template.backends.jinja2.Jinja2
(尽管我认为没有必要)。