101

What is the best location to put templates in django project?

Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
Vishal
  • 19,879
  • 23
  • 80
  • 93

10 Answers10

98

Placed in <PROJECT>/<APP>/templates/<APP>/template.html for app-specific templates to help with making the app reusable elsewhere.

For general "global" templates I put them in <PROJECT>/templates/template.html

dlrust
  • 2,433
  • 19
  • 20
  • 11
    Wondering the reason for 2 ``s in `//templates//template.html`? – David Xia Mar 09 '12 at 07:33
  • 18
    The first /app/templates is just to group templates with their relevant app. The second app is to prevent name collisions. (Presumably, you'll point TEMPLATE_DIRS to point to each of these directories, but in the end, Django lumps them together into one giant directory.) See: https://docs.djangoproject.com/en/dev/ref/templates/api/#using-subdirectories – Ceasar Mar 26 '12 at 23:05
  • 3
    For this to work (django 1.6), I had to add directive for the file system template loader: `TEMPLATE_DIRS = (os.path.join(BASE_DIR, "templates"))` – Fafaman Jun 30 '14 at 13:41
  • 6
    This answer is ancient, but somehow I ended up here. For the record, `TEMPLATE_DIRS` is now deprecated - you should instead add `DIRS=[os.path.join(BASE_DIR, "templates")]` to `TEMPLATES` - see https://stackoverflow.com/questions/29725132/django-cant-find-template-directory – John Aaron Jun 07 '19 at 23:41
52

From the Django book, chapter 4:

If you can’t think of an obvious place to put your templates, we recommend creating a templates directory within your Django project (i.e., within the mysite directory you created in Chapter 2, if you’ve been following along with our examples).

This is exactly what I do, and has worked great for me.

My directory structure looks something like this:

/media for all my CSS/JS/images etc
/templates for my templates
/projectname for the main project code (i.e. the Python code)

bfox
  • 274
  • 2
  • 13
Dominic Rodger
  • 97,747
  • 36
  • 197
  • 212
  • 2
    when you put the templates in /templates, is there a way to tell the template loader to load it without specifying the full path to /template in TEMPLATE_DIRS to load with django.template.loaders.filesystem.Loader? It would be great to do this with a relative path, and under 1.4 my loader is not looking under /templates – Ciro Santilli OurBigBook.com Oct 09 '12 at 16:21
10

DJANGO 1.11

add templates folder where the manage.py exist,which is your base directory. change the DIRS for TEMPLATES as following in your settings.py

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

TEMPLATES = [
{
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [os.path.join(BASE_DIR, 'templates')],
    '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',
        ],
    },
},

]

Now to use the template by using the code ,

def home(request):
    return render(request,"index.html",{})

in views.py. this works completely fine for django 1.11

Alan Paul
  • 139
  • 1
  • 4
9

Following up from Dominic and dlrust,

We use a setuptools source distribution (sdist) to package our django project and apps to deploy in our different environments.

We have found that the templates and static files need to be under the django application directories so that they can be packaged up by setuptools.

For example, our template and static paths look like:

PROJECT/APP/templates/APP/template.html
PROJECT/APP/static/APP/my.js

For this to work, the MANIFEST.in needs to be modified (see http://docs.python.org/distutils/sourcedist.html#the-manifest-in-template)

An example of the MANIFEST.in:

include setup.py
recursive-include PROJECT *.txt *.html *.js
recursive-include PROJECT *.css *.js *.png *.gif *.bmp *.ico *.jpg *.jpeg

Also, you need to confirm in your django settings file that the app_directories loader is in your TEMPLATE_LOADERS. I think it's there by default in django 1.4.

An example of the django settings template loaders:

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
)

Just in case you are wondering why we use sdists instead of just coping rsync files; it's part of our configuration management workflow where we have a single build tarball that is deployed with PIP unchanged into test, acceptance and production environments.

  • 1
    +1 Thank you for providing the extra detail and example lines. – gotgenes Nov 28 '12 at 15:38
  • +1 smart to include `/static/` in your layout plan when thinking about templates and modular apps. You may want to mention another best practice, putting `css` files in a folder called `static/app/css` likewise for `js` and maybe `jpg` or just `/static/app/images`. – hobs Jul 31 '13 at 04:10
3

Django 1.10

TEMPLATE_DIRS is deprecated.

Now we need to use TEMPLATE, introducing in Django 1.8 like this:

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

Once you have defined TEMPLATES, you can safely remove ALLOWED_INCLUDE_ROOTS, TEMPLATE_CONTEXT_PROCESSORS, TEMPLATE_DEBUG, TEMPLATE_DIRS, TEMPLATE_LOADERS, and TEMPLATE_STRING_IF_INVALID.

About the best location, Django looking for template like this :

  • DIRS defines a list of directories where the engine should look for template source files, in search order.
  • APP_DIRS tells whether the engine should look for templates inside installed applications. Each backend defines a conventional name for the subdirectory inside applications where its templates should be stored.

More information : https://docs.djangoproject.com/en/1.10/topics/templates/#configuration

Wilfried
  • 1,623
  • 1
  • 12
  • 19
1

This is more a personal choice at the project-level. If you are talking about apps that need to be pluggable, then a templates directory in your app is the place where they go default. But project-wide, it is what works best for you.

SleighBoy
  • 501
  • 3
  • 12
1

I understood TEMPLATE_DIRS requires an absolute path. And I don't like absolute paths in my code. So this is working well for me, in settings.py:

import os

TEMPLATE_DIRS = (
    os.path.join(os.path.dirname(os.path.realpath(__file__)),
                 "../APPNAME/templates")
)
the
  • 21,007
  • 11
  • 68
  • 101
  • 1
    Django projects have their base path defined already in the standard settings.py as `BASE_DIR`, so you can simplify this to: `os.path.join(BASE_DIR, '../APPNAME/templates')` – ngoue Feb 05 '17 at 16:32
0

You could also consider having your templates in a database, using django-dbtemplates. It is also setup for caching, and the django-reversion application which helps you keep old versions of your templates around.

It works quite well, but I'd prefer a little more flexibility on the import/sync to/from filesystem side.

[edit: 20 Aug 2018 - this repository is no available, one with the same name is available at https://github.com/jazzband/django-dbtemplates and was updated 8 months ago. I no longer use Django in any meaningful way, so can't vouch for this.]

TonyM
  • 171
  • 1
  • 7
  • When would this be a good idea? Isn't it slower to load templates from the DB? – jguffey Jan 21 '14 at 23:18
  • Dont you become dependent on db if you store templates in db plus will you make your db a part of git commits? How will you coordinate between the changes made by different users in the templates? – gautamaggarwal Jul 15 '18 at 07:19
  • This was written way before I became aware of git. Not even sure I was using svn at the time. I'd recommend using version control systems now. – TonyM Jul 19 '18 at 01:24
  • @tonemcd, this repository has been deleted. – lmiguelvargasf Jul 27 '18 at 00:47
0

Previous solution didn't work in my case. I used:

TEMPLATE_DIRS = [ os.path.join(os.path.dirname(os.path.realpath(__file__)),"../myapp/templates") ]
the
  • 21,007
  • 11
  • 68
  • 101
  • Look my answer. `TEMPLATE_DIRS` is deprecated now. – Wilfried Feb 05 '17 at 10:43
  • Django projects have their base path defined already in the standard settings.py as `BASE_DIR`, so you can simplify this to: `os.path.join(BASE_DIR, '../myapp/templates')` – ngoue Feb 05 '17 at 16:33
0

templates folder just under django-project is the best location as shown below because we can more easily manage templates in one place than templates folder just under each app folder. You can see my answer explaining how to set templates folder in detail:

django-project
 |-core
 │  |-settings.py
 │  └-urls.py
 |-app1
 |  |-urls.py
 |  └-views.py
 |-app2
 |  |-urls.py
 |  └-views.py
 └-templates # Here
    |-app1
    |  └-a1.html
    └-app2
       └-a2.html

Then, so that templates folder just under django-project can be found, you need to set BASE_DIR / 'templates' to "DIRS" in TEMPLATES in settings.py as shown below:

# "settings.py"

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [
            BASE_DIR / 'templates', # Here
        ],
        "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",
            ],
        },
    },
]
Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129