27👍
Frist you have to install jinja2
:
$ pip install Jinja2
Then modify your TEMPLATES
list in the settings.py to contain the 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',
],
},
},
]
where templates/jinja2
is the directory with your jinja2 template files.
And in your views.py file:
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
This makes static
and url
available in your Jinja2 templates.
P.S. For more details see this article.
16👍
Took me quite some time to figure out everything, answers here weren’t all that helpful.
doru’s answer is closest to truth but is incomplete.
How to use jinja as templating language:
1.Create jinja2.py file in your project folder. This is required to modify the default jinja2 Environment (in our case, passing some additional global variables).
location: {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.Add jinja2 backend to django project settings file, including our modified environment.
TEMPLATES = [
{
'BACKEND': 'django.template.backends.jinja2.Jinja2',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'environment': "main.jinja2.environment",
},
},
...
]
3.Now you no longer need to import jinja2 anywhere, in your views, you will be using jinja templates through django just like django templates:
from django.shortcuts import render
def index(request, **kwargs):
return render(request, "index.html.j2", {'title': 'MyTitle', 'text': "MyText"})
And finally, with APP_DIRS set to True jinja will search templates in all installed apps jinja2
directories. (unlike DTL that searches for templates
folder). If you want to change that behavior, or want some extra tweaking, like extension match, filtering or global variables, you should look at django-jinja extension.
You may also provide additional directories to search for templates via TEMPLATES['DIRS']
option of settings.
- [Django]-Unicode vs UTF-8 confusion in Python / Django?
- [Django]-Django models: Only permit one entry in a model?
- [Django]-Django runserver hangs at "System check identified no issues (0 silenced)."
2👍
Mixed Django and Jinja2 Template: Environment: Django 1.8 + Jinja2.
I have some legacy Django templates and it’s not so easy to rewrite them all at once to Jinja2, so add this custom {% jinja_include "some_template.jinja" %}
tag to 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())
Call it like this from your Django template:
{% load my_custom_tags %}
{% jinja_include "some_template.jinja" %}
- [Django]-AttributeError: module Django.contrib.auth.views has no attribute
- [Django]-Interactive Graphviz graphs in a web application
- [Django]-Django Filter Query Foreign Key
2👍
Update for Django 3+: Real Life config Jinja2 3.0.X +
<project_name>/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",
],
},
},]
<project_name>/<project_name>/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')
)
<project_name>/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)
<project_name>/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 %}
<project_name>/ui/templatetags/extras.py # Bonus, FYI
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]-Oauth for Google API example using Python / Django
- [Django]-Apache + mod_wsgi vs nginx + gunicorn
- [Django]-How do I see the Django debug toolbar?
0👍
From the Django website (please look at this for further guidance) in settings.py
:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
# ... some options here ...
},
},
]
BACKEND is a dotted Python path to a template engine class implementing Django’s template backend API. The built-in backends are django.template.backends.django.DjangoTemplates and django.template.backends.jinja2.Jinja2.
Basically find out where in your settings.py file there is a TEMPLATES variable and set the backend (or make sure the backend) resembles the one above (as Jinga is built-in). If all fails, replace the django.template.backends...
with django.template.backends.jinja2.Jinja2
(though I don’t think that is necessary).
- [Django]-Django migration strategy for renaming a model and relationship fields
- [Django]-How can I find the union of two Django querysets?
- [Django]-How to use Django model inheritance with signals?