tags:

views:

64

answers:

3

I started going through The Definitive Guide to Django and now would like to start working on my own project. I have Django set up and everything. I created a project called djangoproject1. Basically what I would like is that the main page is a registration/login page. My urls.py for djangoproject1 looks like this:

urlpatterns = patterns('',
    (r'^/',include('djangoproject1.authentication.urls')),
)

I have a pydev package (application) under djangoproject1 called authentication which has an urls.py that looks like this:

urlpatterns = patterns('',
    (r'^$',direct_to_template,{'template':'index.html'}),
)

A couple of questions:

  1. I'm getting a page not found error which means I'm probably doing my mapping/include incorrectly
  2. If I don't specify anything under TEMPLATE_DIRS in settings.py, my understanding is that Django will look in each package for a directory named templates. Is that correct?
A: 

Yes, Django will search in other place's, but you NEED a template directory under your project.

Asinox
I made sure to put a templates directory under the main project as well as one under my authentication package. I think the problem is with how I'm including.
JPC
+1  A: 

Django will NOT automatically look for a templates directory, but there is a template loader (that comes by default) in settings.py called django.template.loaders.app_directories.Loader that will. I reccomend NOT using this because it does not namespace your templates. This means that a template called index.html under an appone/templates will hide a template called index.html under apptwo/templates (if apptwo is below appone in INSTALLED_APPS.

Matthew J Morrison
having said that - you SHOULD still have a templates directory under each app to organize your templates, but I would recommend always explicitly listing full paths to your templates so you're sure that you know which one you're getting.
Matthew J Morrison
thanks, thats a helpful hint!so in my urls.py in the authentication package, what should my template dictionary specify? 'djangoproject1.authentication.templates.index.html'? That seems wrong because templates isn't a package
JPC
correct, it isn't a package, it is just a file on the file system. "djangoproject1/authentication/templates/index.html"
Matthew J Morrison
+2  A: 

What Asinox has said is not true. You MAY have a global template directory, even several of them. But that is not a must.

In fact template loading is done as follows:

  1. Django takes first class name from TEMPLATE_LOADERS settings variable
  2. It instantiates the template loader based on its name
  3. It tries to load the template using this instance
  4. If it succeeds - the template is returned
  5. If if fails to load the template - it takes the next name and starts over again from 2.
  6. If none of the template loaders listed in TEMPLATE_LOADERS managed to load the template TemplateDoesNotExist exception is raised

By default TEMPLATE_LOADERS is set to

TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.load_template_source',
    'django.template.loaders.app_directories.load_template_source',
)

As Matthew stated TEMPLATE_DIRS is used solely by filesystem.load_template_source loader. So if you exclude it from the list it won't have any impact on template loading process at all.

In order for your template to be found I'd suggest you to do the following:

  • Make your index.html namespaced, i.e. put it as follows:
.
`-- djangoproject1
    `-- authentication
        `-- templates
            `-- authentication
                `-- index.html
  • Load the template namespaced:

    urlpatterns = patterns('',
        (r'^$', direct_to_template, {'template': 'authentication/index.html'}),
    )

Unless you do so you cannot be sure that Django loads index.html from the authentication application.

Consider the behavior of app_directories.load_template_source template loader.

Pretend you have just defined two applications app1 and app2 (no other apps are defined) and asked to load template 'path/to/template.html'.

The loader will check the following paths in no particular order:

  • project_root/app1/templates/path/to/template.html
  • project_root/app2/templates/path/to/template.html
Ihor Kaharlichenko
So really if I use the app_directories loader only, I don't need the file system loader and don't need the template_dirs. By namespacing my templates like you did it works perfectly. Thanks
JPC
this namespacing only works until you get templates/main/index.html in multiple apps...
Matthew J Morrison
I'll have to keep my names different for the time being I guess
JPC