109

I want to use the Django template engine in my (Python) code, but I'm not building a Django-based web site. How do I use it without having a settings.py file (and others) and having to set the DJANGO_SETTINGS_MODULE environment variable?

If I run the following code:

>>> import django.template
>>> from django.template import Template, Context
>>> t = Template('My name is {{ my_name }}.')

I get:

ImportError: Settings cannot be imported, because environment variable DJANGO_SETTINGS_MODULE is undefined.
Josh Scholl
  • 143
  • 15
Daryl Spitzer
  • 143,156
  • 76
  • 154
  • 173

15 Answers15

138

The solution is simple. It's actually well documented, but not too easy to find. (I had to dig around -- it didn't come up when I tried a few different Google searches.)

The following code works:

>>> from django.template import Template, Context
>>> from django.conf import settings
>>> settings.configure()
>>> t = Template('My name is {{ my_name }}.')
>>> c = Context({'my_name': 'Daryl Spitzer'})
>>> t.render(c)
u'My name is Daryl Spitzer.'

See the Django documentation (linked above) for a description of some of the settings you may want to define (as keyword arguments to configure).

Daryl Spitzer
  • 143,156
  • 76
  • 154
  • 173
  • 13
    And to get it from a file: settings.configure( TEMPLATE_DIRS=(".",) ) t = get_template('test.html') – Bryce Sep 16 '13 at 06:51
  • The documentation for settings.configure() is here - https://docs.djangoproject.com/en/1.7/topics/settings/ – Scott Feb 28 '15 at 05:52
  • From the "well documented" link above, this is true up to version 1.7. Starting from 1.8, it seems you don't need `settings.configure()` anymore. – Olaf Dietsche Jul 27 '15 at 19:56
  • If you want to include other templates, or use template inheritance, the solution above by Bryce is necessary. – titusjan Nov 11 '15 at 11:38
  • How do I load apps like `mathfilters` in this approach? – oarfish Dec 02 '15 at 13:47
  • 7
    I additionally needed to call django.setup() before the Template constructor. – Amit Jan 19 '16 at 09:33
  • I am using django 3.0.8 and need to specify TEMPLATES in a way like `settings.configure(TEMPLATES=TEMPLATES)` – kayochin Jul 25 '20 at 15:45
47

Jinja2 syntax is pretty much the same as Django's with very few differences, and you get a much more powerfull template engine, which also compiles your template to bytecode (FAST!).

I use it for templating, including in Django itself, and it is very good. You can also easily write extensions if some feature you want is missing.

Here is some demonstration of the code generation:

>>> import jinja2
>>> print jinja2.Environment().compile('{% for row in data %}{{ row.name | upper }}{% endfor %}', raw=True) 
from __future__ import division
from jinja2.runtime import LoopContext, Context, TemplateReference, Macro, Markup, TemplateRuntimeError, missing, concat, escape, markup_join, unicode_join
name = None

def root(context, environment=environment):
    l_data = context.resolve('data')
    t_1 = environment.filters['upper']
    if 0: yield None
    for l_row in l_data:
        if 0: yield None
        yield unicode(t_1(environment.getattr(l_row, 'name')))

blocks = {}
debug_info = '1=9'
nosklo
  • 217,122
  • 57
  • 293
  • 297
  • 4
    I'm using Jinja in a project of mine, because I wanted something that I was fairly familiar with, but didn't want my users (since it's a distributable app) to have to install Django. A plus is that Jinja can be installed with easy_install. – Xiong Chiamiov Jul 16 '09 at 23:55
  • 4
    Django can be installed with easy_install as well. – hegemon Mar 22 '10 at 10:45
  • Jinga doesn't officially support Python3 yet. According to the site, It's still experimental. – Pramod Dec 28 '15 at 13:10
10

Any particular reason you want to use Django's templates? Both Jinja and Genshi are, in my opinion, superior.


If you really want to, then see the Django documentation on settings.py. Especially the section "Using settings without setting DJANGO_SETTINGS_MODULE". Use something like this:

from django.conf import settings
settings.configure (FOO='bar') # Your settings go here
John Millikin
  • 197,344
  • 39
  • 212
  • 226
9

An addition to what other wrote, if you want to use Django Template on Django > 1.7, you must give your settings.configure(...) call the TEMPLATES variable and call django.setup() like this :

from django.conf import settings

settings.configure(TEMPLATES=[
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': ['.'], # if you want the templates from a file
        'APP_DIRS': False, # we have no apps
    },
])

import django
django.setup()

Then you can load your template like normally, from a string :

from django import template   
t = template.Template('My name is {{ name }}.')   
c = template.Context({'name': 'Rob'})   
t.render(c)

And if you wrote the DIRS variable in the .configure, from the disk :

from django.template.loader import get_template
t = get_template('a.html')
t.render({'name': 5})

Django Error: No DjangoTemplates backend is configured

http://django.readthedocs.io/en/latest/releases/1.7.html#standalone-scripts

Robert Vanden Eynde
  • 681
  • 1
  • 7
  • 18
7

I would also recommend jinja2. There is a nice article on django vs. jinja2 that gives some in-detail information on why you should prefere the later.

user7610
  • 25,267
  • 15
  • 124
  • 150
olt
  • 2,267
  • 1
  • 19
  • 13
  • I prefer Jinja2 because of `{% set %}` syntax and equality to Twig template engine (PHP). It's better to write cross platform code always, but the performance difference is not critical - for example, **python will always work slower than PHP** so if you need performance you better create site with PHP, Twig and Symfony2 or else. Sad but truth. – Croll Nov 16 '15 at 22:31
  • @Croll, If your website performs complex computations then python libraries are uncomparebly faster, otherwise the bottleneck is database or you are likely doing something really wrong way – Bob Aug 24 '17 at 11:10
5

According to the Jinja documentation, Python 3 support is still experimental. So if you are on Python 3 and performance is not an issue, you can use django's built in template engine.

Django 1.8 introduced support for multiple template engines which requires a change to the way templates are initialized. You have to explicitly configure settings.DEBUG which is used by the default template engine provided by django. Here's the code to use templates without using the rest of django.

from django.template import Template, Context
from django.template.engine import Engine

from django.conf import settings
settings.configure(DEBUG=False)

template_string = "Hello {{ name }}"
template = Template(template_string, engine=Engine())
context = Context({"name": "world"})
output = template.render(context) #"hello world"
Pramod
  • 5,150
  • 3
  • 45
  • 46
3

Thanks for the help folks. Here is one more addition. The case where you need to use custom template tags.

Let's say you have this important template tag in the module read.py

from django import template

register = template.Library()

@register.filter(name='bracewrap')
def bracewrap(value):
    return "{" + value + "}"

This is the html template file "temp.html":

{{var|bracewrap}}

Finally, here is a Python script that will tie to all together

import django
from django.conf import settings
from django.template import Template, Context
import os

#load your tags
from django.template.loader import get_template
django.template.base.add_to_builtins("read")

# You need to configure Django a bit
settings.configure(
    TEMPLATE_DIRS=(os.path.dirname(os.path.realpath(__file__)), ),
)

#or it could be in python
#t = Template('My name is {{ my_name }}.')
c = Context({'var': 'stackoverflow.com rox'})

template = get_template("temp.html")
# Prepare context ....
print template.render(c)

The output would be

{stackoverflow.com rox}
Gourneau
  • 12,660
  • 8
  • 42
  • 42
2

I would say Jinja as well. It is definitely more powerful than Django Templating Engine and it is stand alone.

If this was an external plug to an existing Django application, you could create a custom command and use the templating engine within your projects environment. Like this;

manage.py generatereports --format=html

But I don't think it is worth just using the Django Templating Engine instead of Jinja.

muhuk
  • 15,777
  • 9
  • 59
  • 98
1

Don't. Use StringTemplate instead--there is no reason to consider any other template engine once you know about it.

Paul D. Waite
  • 96,640
  • 56
  • 199
  • 270
Rob Williams
  • 7,919
  • 1
  • 35
  • 42
1

Found this:

http://snippets.dzone.com/posts/show/3339

Lou Franco
  • 87,846
  • 14
  • 132
  • 192
0

While running the manage.py shell:

>>> from django import template   
>>> t = template.Template('My name is {{ me }}.')   
>>> c = template.Context({'me': 'ShuJi'})   
>>> t.render(c)
Pedro Romano
  • 10,973
  • 4
  • 46
  • 50
hupantingxue
  • 2,134
  • 3
  • 19
  • 24
0

All of the current examples still need to initialize the configuration system. This bypasses it:

#!/usr/bin/env python3

import django.template
import django.template.engine

def _main():
    e = django.template.engine.Engine()

    body = """\
aa {{ test_token }} cc
"""

    t = django.template.Template(body, engine=e)

    context = {
        'test_token': 'bb',
    }

    c = django.template.Context(context)
    r = t.render(c)

    print(r)


_main()

Output:

$ ./test_render.py 
aa bb cc
Dustin Oprea
  • 9,673
  • 13
  • 65
  • 105
0

In the case where you need to use custom template tags, @Gourneau's answer did not work for me. I had to configure settings (in my main.py) like this:

import django
from django.conf import settings
from django.template.loader import get_template

settings.configure(
    TEMPLATES=[
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': ['templates'],
        'APP_DIRS': False,
        'OPTIONS': {
            'libraries': {
                'custom_filters': 'templatetags.custom_filters',
            },
        },
    },
])
django.setup()

where my folder structure looks like this:

- main.py
- templates/
  - test_results.html
- templatetags/
  - __init__.py
  - custom_filters.py

and custom_filters.py looks like this:

from django import template
import pandas as pd
import base64
from django.utils.safestring import mark_safe

register = template.Library()

@register.filter
def nl_to_br(string:str):
    return mark_safe( string.replace("\n", "<br>") )

Now I could simply use (in main.py):

template = get_template('test_results.html')
context = {
    "results": results
}
test_results = template.render(context)
0

Google AppEngine uses the Django templating engine, have you taken a look at how they do it? You could possibly just use that.

Hedde van der Heide
  • 21,841
  • 13
  • 71
  • 100
William Keller
  • 5,256
  • 1
  • 25
  • 22
0

I echo the above statements. Jinja 2 is a pretty good superset of Django templates for general use. I think they're working on making the Django templates a little less coupled to the settings.py, but Jinja should do well for you.

Clint Ecker
  • 1,522
  • 1
  • 10
  • 12