34

I'm experimenting with Django, and figuring out how to set urls.py, and how the URLs work. I've configured urls.py in the root of the project, to directs to my blog and admin. But now I want to add a page to my home, so at localhost:8000.

So I've added to following code to the urls.py in the root of the project:

from django.views.generic.simple import direct_to_template

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

The problem is that it searches for the template in blog/templates/... Instead of the templates folder in my root. Which contains the base.html.

Full urls.py:

from django.conf.urls import patterns, include, url
from django.views.generic.simple import direct_to_template

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()


urlpatterns = patterns('',
    (r"^$", direct_to_template, {"template": "base.html"}),
    url(r'^blog/', include('hellodjango.blog.urls')),
    url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
    url(r'^admin/', include(admin.site.urls)),
    (r'^tinymce/', include('tinymce.urls')),
)

Am I overlooking something?

daaawx
  • 3,273
  • 2
  • 17
  • 16
Kevinvhengst
  • 1,672
  • 4
  • 27
  • 40

5 Answers5

66

Did you set TEMPLATE_DIRS in your settings.py? Check and make sure it is set up correctly with absolute paths. This is how I make sure it is properly set:

settings.py

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

TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    os.path.join(PROJECT_ROOT, 'templates').replace('\\','/'),
)

# 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',
#     'django.template.loaders.eggs.Loader',
)

This way, I have a templates folder in my project root that is used for non-app templates and each app has a templates/appname folder inside the app itself.

If you want to use a template from the root template folder, you just give the name of the template like 'base.html' and if you want to use an app template, you use 'appname/base.html'

Folder structure:

project/
  appname/
    templates/ 
      appname/  <-- another folder with app name so 'appname/base.html' is from here
        base.html
    views.py
    ...

  templates/    <-- root template folder so 'base.html' is from here
    base.html

  settings.py
  views.py
  ...
Ngenator
  • 10,909
  • 4
  • 41
  • 46
  • Thx! I modified the settings in setteings.py, and everything is working as intended! thx alot :) i still find it hard to figure out some poblems which has to do with the settings.py. Im glad it's working. Thx alot! – Kevinvhengst Mar 15 '13 at 06:52
  • @KevinvanHengst No problem, when I started I ran into similar problems and had to go digging for an answer for quite a while, glad I could help. – Ngenator Mar 15 '13 at 11:37
  • Thanks for the great answer. I'm doing this now and app templates work, but extending a project template doesn't. Template loader keeps searching only within the app folder. Any suggestions? – cbrad Jul 19 '15 at 00:14
  • 8
    This is good, for django 1.9 the variable you want to update is "DIRS" located in "TEMPLATES =" and since the default project root is BASE_DIR it should look like this in the TEMPLATES dict: 'DIRS': [os.path.join(BASE_DIR, 'templates').replace('\\','/'),], – Ezekiel Kruglick Jan 26 '16 at 20:11
  • this method is deprecated in Django +1.9. – Ali Akhtari Jan 02 '21 at 10:22
4
from django.conf.urls import patterns, include, url

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()


urlpatterns = patterns('',
    url(r'^blog/', include('hellodjango.blog.urls')),
    url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
    url(r'^admin/', include(admin.site.urls)),
    url(r'^tinymce/', include('tinymce.urls')),
)

urlpatterns += patterns(
    'django.views.generic.simple',
    (r'^', 'direct_to_template', {"template": "base.html"}),
)
catherine
  • 22,492
  • 12
  • 61
  • 85
2

I would re-organize the urls as such:

urlpatterns = patterns('',
    (r'^admin/doc/', include('django.contrib.admindocs.urls')),
    (r'^admin/', include(admin.site.urls)),
    (r'^tinymce/', include('tinymce.urls')),
    (r'^blog/', include('hellodjango.blog.urls')),
    (r'^$', direct_to_template, {"template": "base.html"}),
)

Patterns are matched by their specificity, so I tend to put the more specific patterns first. Otherwise you might see some unexpected behavior. Give that a try, and if it's still loading a template from your blog on a request to /, we'll dig deeper.

Brandon Taylor
  • 33,823
  • 15
  • 104
  • 144
  • It's still trying to load templates from blog/templates. I've looked into the settings.py if i screwed up something with TEMPLATE_DIR, but didnt specify one. So im still curious how it gets this path. – Kevinvhengst Mar 14 '13 at 14:14
  • I would recommend setting a templates directory. – Brandon Taylor Mar 14 '13 at 14:58
  • Yes, look into the ``TEMPLATE_DIR`` in ``settings.py`` and you'll find something. Read more about that setting in Django documentation and you'll probably fix it. – Erica Xu Mar 14 '13 at 16:47
  • @Brandon Would the ordering matter in this scenario? He properly terminates the regex for the root with `$` so that would only match the root url `/` I get that ordering it like that would be more readable, just wondering if it would actually affect where django looks for templates. – Ngenator Mar 14 '13 at 16:59
  • Also confused by the missing `url` before 2 of the patterns lol – Ngenator Mar 14 '13 at 17:07
  • Yes, the there's really no need to have url specified for a set of patterns you're including. I think the problem is caused by not specifying a templates directory. – Brandon Taylor Mar 14 '13 at 17:34
0

I think it depends what you want your home page to be. If its simply a page with links off to other parts of your site then catherine's answer is a nice clean way.

If you want the root of your site to be your blog for example I would do this:

urlpatterns = patterns('',
    # Django Admin
    url(r'^admin/', include(admin.site.urls)),
    # Tiny MCE Urls
    url(r'^tinymce/', include('tinymce.urls')),
    # Other App
    url(r'^other/', include('projectname.other.urls', namespace='other')),
    # Blog App
    url(r'^', include('projectname.blog.urls', namespace='blog')),
)

Also don't forget to name space your url includes: https://docs.djangoproject.com/en/dev/topics/http/urls/#url-namespaces

Community
  • 1
  • 1
krak3n
  • 948
  • 6
  • 13
0

you can refer the my solution

Django==3.2.5

https://stackoverflow.com/a/68420097/10852018

Mr Coder
  • 507
  • 3
  • 13