Django Templates: How does it decide where to load a template? - django

I was following the Django Girls Tutorial up to the point where we add the login capabilities and I've gotten to a point where it tries to load from a different template folder than I want.
I have all my blog templates in blog\templates\blog\, etc. and that is where Django is looking for my login.html. However, in the tutorial (and as a result in my folder structures), the path for login.html is: mysite/templates/registration/login.html. So how would I make Django look there?
Sorry if this is a stupid question.

Django will look to your settings.py for how to load templates, and the order in which it should try to load templates. It's likely that you haven't configured django to look for templates in mysite/templates.
There's a setting called TEMPLATE_DIRS which is a list of absolute paths for your template folders. So in your settings.py file, try something like below. Read my comments to see what each line does.
# create a variable that stores the absolute path to your project's root directory
# you might have something like this already defined at the top of your settings.py
BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
# this is the default value for TEMPLATE_LOADERS
# which says to look at the `TEMPLATE_DIRS` variable, and then in each of your app's subdirectories for templates
TEMPLATE_LOADERS = ('django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader')
# the special sauce. tell django to look at the "templates" folder
TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'templates'), )

Related

Adding new template folder in Django

Say I have the following folder structure
mysite
- mysite
- templates
- books
- templates
- contact
- templates
And I have the following in my settings.py
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),
)
How would I configure the site to look in the templates folder of any sub directory? For example, say I wanted to add another folder to my existing 3 (mysite, books, contact) called "test". I would want the site to automatically know to search in "test/templates".
I am wondering if it is as simple as:
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),
os.path.join(os.path.dirname(__file__), 'mysite/templates').replace('\\','/'),
os.path.join(os.path.dirname(__file__), 'books/templates').replace('\\','/'),
os.path.join(os.path.dirname(__file__), 'contact/templates').replace('\\','/'),
)
To me, that looks like it would point to "/mysite/books/templates" not "/books/templates"
I use something like this:
TEMPLATE_DIRS = (
join(BASE_DIR, 'templates'),
)
And then i put all my templates under the templates folder (which is under the same directory as manage.py). This way i can find all the templates for my project in the same place.
+templates
-app1 templates
-app2 templates
When i need to access a template i just use 'app1/my_template.html'.

Templates in shared apps

I have two django projects that share some common apps,
this is my structure:
prj_1
prj_2
common_apps
From prj_1 and prj_2 I use the common apps and I'd like to render these apps with different templates.
How can I do?
Yes, using the following directory structure:
common_apps
app1
templates
app1
# default templates for common app live here
prj_1
templates
app1
# overridden templates for app1 live here (using same file name)
This isn't clearly spelled out in the docs in one place, but your prj_1 templates will override common_apps because the default setting in Django looks like:
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
...and your typical Django settings file will have something like this:
TEMPLATE_DIRS = (
os.path.join(PROJECT_ROOT, 'templates'),
# where PROJECT_ROOT is absolute path to prj_1/
)
...which means when looking for say 'app1/base.html' the filesystem.Loader will get called first and will find any overridden templates in prj_1 so app_directories.Loader won't get called.
Some info here:
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-admin-templates

Tell django to search app's template subfolders

I have the following folder structure for the templates on my django app:
templates/
app/
model1/
model1_form.html
model2/
model2_form.html
Suppose I'm using model1 and a generic ListView, right now it only searches at templates/app/model1_form.html. Is there anyway I can tell django he should also search the app/ subfolders? I don't want to have to set the template name and path manually (template_name="templates/app/model1/model1_form.html").
At settings.py I have:
import os.path
BASE_PATH = os.path.dirname(os.path.dirname(__file__))
TEMPLATE_DIRS = (
BASE_PATH+'/templates/',
)
This is my view:
class HousesListView(ListView):
model = House
context_object_name = "house_list"
Thanks in advance!
The other answers were correct at the time, but for anyone coming across this now, this is how this is done in Django 1.8+
By default, Django now looks in app folders for templates. This is indicated by 'APP_DIRS': True, in the TEMPLATES setting like this:
TEMPLATES = [
{
...
'DIRS': ['templates'],
'APP_DIRS': True,
...
},
]
As the other answers indicate, you should still use appname/templates/appname/model1_form.html to namespace the templates
( more info: https://docs.djangoproject.com/en/1.8/intro/tutorial03/#write-views-that-actually-do-something in the box titled 'template namespacing')
Final check: make sure the app you're using is in the INSTALLED_APPS tuple, as that was the problem I was having.
You need to add django.template.loaders.app_directories.Loader to TEMPLATE_LOADERS (if it's not already).
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
Then, change your folder structure such that you have a "templates" folder in the app directory:
- <project_root>
- app
- templates
- model1
- model2
Or to properly namespace the models so they don't clash with other app names accidentally:
- <project_root>
- app
- templates
- app
- model1
- model2
I think to use templates from subfolders generally you either have to:
Manually give the template path as subdir/template.html
eg. render_to_response('sub/dir/template.html') or template_name='...'
Define all the subfolders in the TEMPLATE_DIRS
eg.
TEMPLATE_DIRS = (
BASE_PATH+'/templates/',
BASE_PATH+'/templates/app',
BASE_PATH+'/templates/app/model1',
)
But because Generic Views except templates to be found in app_name/template.html,
you would have to move your templates to add /path/to/templates/app/model1 to your TEMPLATE_DIRS, and move your templates to templates/your_app/model/your_app/model_template.html, which is little bit awkward.
With Django 2.0, it's not even necessary to change anything in the TEMPLATES variable in settings.py.
The only requirement is to add appname.apps.AppnameConfig (e.g. catalog.apps.CatalogConfig for an app named 'catalog') to the INSTALLED_APPS list, then django will look under appname/templates when it searches for templates.

Getting Page not found (404) in Django 1.3.1 from bad url pattern

I am following along with this Django blog tutorial and can not get the url pattern given in the tutorial to work properly. The url.py code the author gives is
(r'^static/(?P
.*)$', 'django.views.static.serve',
{'document_root': 'c:/static/adornment'}),)
and I adapted it to my Linux set up like this
from django.conf.urls.defaults import patterns, include, url
urlpatterns = patterns('',
(r'^static/(.*)$', 'django.views.static.serve',
{'document_root': '/home/sez/blog/static/image.png'}
),
)
and after going to http://127.0.0.1:8000/static/image.png I received the following error
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/static/image.png
'image.png' could not be found
How can I make this work?
Change up your 'document_root' to be a directory, and make sure your STATIC_URL setting is set to /static/
The likely reason for the behavior you were experiencing is as follows. You probably have 'django.contrib.staticfiles' included in your INSTALLED_APS in the "settings.py" file. In that case, when you run "manage.py runserver" (and you have DEBUG = True in your "settings.py"), static files will be automatically served from your STATIC_URL by the staticfiles app and not by your 'django.views.static.serve' URL pattern. However, in your case staticfiles app is not set up correctly and won't find your 'image.png' file. You might want to read more about conventional serving of static files here: Managing static files.
For that matter, STATIC_URL is not supposed to be a filesystem path like you have now: STATIC_URL.
When you made it that way, you effectively disabled staticfiles app and your code started working as a result :)
So, to solve your problem "correctly", you need to either make sure that STATIC_URL and the URL path in your "urls.py" are different, for example, make one of them "/static/" and another one "/media/" (or something else), or just remove "django.contrib.staticfiles" from your INSTALLED_APPS altogether if you don't use it. (And, of course, the advice about making 'document_root' a directory was entirely correct. You can read more about using 'django.views.static.serve' here: Serving static files in development.)

Django custom locale directory

I'm developing a project with two different sites, divided by
language. Maybe I was terribly wrong, but now my directory structure
looks like:
/ruapp/settings.py # SITE_ID = 1
/ruapp/manage.py
/enapp/settings.py # SITE_ID = 2
/enapp/manage.py
/common/urls.py
/common/ # almost every other file
/common/templates/ # templates with {% trans %}
/locale/ # with locales ru-ru and en-us, generated by calling
makemessages from the root of all this structure
How to tell django about the locale? It does not seem like it will
find the /locale/ folder by itself
AFAIK, python-gettext can't use different folder, so... Use Symlinks, Luke!
Make sure your directory structure for localization files look like that:
locale/en/LC_MESSAGES/django.mo
locale/ru/LC_MESSAGES/django.mo
If you name them something else, or put them elsewhere, it probably won't work.
You also need to pust aproperiate l18n information in your settings file. LANGUAGE_CODE = 'en' in one, and LANGUAGE_CODE = 'ru' in the other.
Edit: Have you created two separate apps or two separate project? Apps usually don't have their own settings.py and manage.py...
You can have one project that have multiple settings files and runs multiple websites. It would be much more django-ish (and much easier to deal with) for your directory structure to look like this:
/settings_ru.py # SITE_ID = 1
/settings_en.py # SITE_ID = 2
/manage.py # use --settings option to distinguish between settings files.
/urls.py
/templates/ # templates with {% trans %}
/locale/ # locale/en/LC_MESSAGES/django.mo and locale/ru/LC_MESSAGES/django.mo
(+ other common code, inside their respective apps)