How does django know how to find templates? (1.2x) - django

Running through the djangobook (ver 2). I had a little trouble with template loading; my relevant filestructure:
testSite/urls.py
testSite/books/views.py
testSite/books/templates/
testSite/contact/views.py
testSite/contact/templates/
When I set-up a view for the books chapter (chap. 5), I was able to create a url in urls.py, point it to a view function in testSite/books/views, but when I called the template from that view function, I did not have to specify a directory - django knew it was in testSite/books/templates.
I tried doing the same thing for the contact form chapter (chap. 7), but this time it would not load the template - I had to go back to settings.py and explicitly place testSite/contact/templates into TEMPLATE_DIRS:
# testSite/settings.py
# ....
TEMPLATE_DIRS = (
'/home/chris/djcode/testSite/templates',
'/home/chris/djcode/testSite/contact/templates',
)
So - is there an obvious explanation as to why I need to point django to the contact/templates folder, but not the books/templates folder?
(If not, I can post more code - trying to keep it short)

You either did not add the contact application to your INSTALLED_APPS in settings.py OR you are trying to load the template from one application inside another application. The TEMPLATE_DIRS is where to look if it doesn’t find the template inside the same application as the views are loading from.

Probably because a Template Loader knows how to find it. The app_directories one will find the templates directory in each application.
django.template.loaders.filesystem.Loader will use the TEMPLATE_DIRS setting.
django.template.loaders.app_directories.Loader will find the templates directory in your installed apps.
If the first loader in the TEMPLATE_LOADERS setting can't find it, Django will ask the next to see if it can find it.
How are you telling your views which templates you're using?

I expect your books app is in INSTALLED_APPS, but contact is not.

Related

Django can't find jade template

I've followed the install guide on pyjade website and rewritten all my templates in my Django project. However, Django doesn't seem to find templates when I use the extends tag in templates.
extends 'base.jade'
When I try to extend another template I get this error.
TemplateDoesNotExist at /
base.jade
Django tried loading these templates, in this order:
Using loader pyjade.ext.django.loader.Loader:
From my settings.py I have
TEMPLATE_LOADERS = (
('pyjade.ext.django.Loader',(
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)),
)
INSTALLED_APPS = (
...
'pyjade',
)
Is there any known bugs with using pyjade together with Django==1.5.4? The project worked fine using ordinary html templates, I have not changed anything about the folder structure.
EDIT: Added settings and more information.
Solved it.
Didn't really have anything to do with Django not finding the template. It was just errors with poor conversion from HTML to Jade, leaving misspells and templatetags that wasn't closed. Although Pyjade is really nice with Django, it has some drawbacks when it comes errors in templates. It just says line 0 and nothing about where the error is located.
If you have the same problem, a tip would be to check your syntax one more time.

django grappelli change_form.html override

I'm trying to extend django's admin change_form.html (django/contrib/admin/templates/admin/change_form.html).
What makes this more complicated for me is that I've installed grappelli, which also extends it (grappelli/templates/admin/change_form.html)
Now, I want to change it in myproject (to apply for all apps/modules in my project), and have tried to place change_form in various places but to no avail:
myproject/templates/admin/change_form.html
myproject/templates/grappelli/change_form.html
myproject/templates/admin/grappelli/change_form.html
Does anyone have a clue about where I should be placing my modified version of change_form.html in order for django to actually use it?
(any help on understanding django's search path & template extension mechanism will be appreciated).
Thanks!
You can include your template directory to TEMPLATE_DIRS
TEMPLATE_DIRS = (
os.path.join(BASE_DIR, 'myapp/templates/'),
)
This way you can change the order in which Django reads your template files.

How to create directory structure

I am not quite sure if my directory structure has the correct hierarchy and I decided to stop the development unless I will have it good.
I have order, customers, users .
So what I have is:
myproj
|-myproj
|-web_app
|---orders (with views.py, ajax.py)
|----templatetags
|---users
|---customers
|---search
|---static
|-----app
|-------_base
|---------css
|---------images
|---------js
|-------orders
|---------css
|---------images
|---------js
|-------customers
|---------css
|---------images
|---------js
|-------users
|---------css
|---------images
|---------js
|-----bootbox
|-----bootstrap
|-------css
|-------fonts
|-------js
|-----dajax
|---templates
models.py is in web_app directory, there are models common for all modules. My questions are:
1) What changes would you do in this structure? (static files for every module should be where?)
2) I have problem of inserting custom template tag defined in orders/templatetags/orders_extras.py from users template. How can I make some common templatetags for every "module" ?
Thank you.
This is explained in Django documentation very well. The good approach is:
Project
- App1
(Put app specfic templates to the app templates/App1/templates/App1/template files
- App2
- App3
- template for project (templates/ files)
Now, if you want template tags only for specific app create /templatetag directory under that app and do that.
For universal template tag do this:
Project
- templatetags
- __init__.py (Make sure it contains __init__.py)
- polltag.py
Explained here: https://docs.djangoproject.com/en/dev/howto/custom-template-tags/
How can I make some common templatetags for every "module" ?
You should place it near the templates directory
myproj
|-myproj
|-web_app
|---templates
|---templatetags
|---orders (with views.py, ajax.py)
|----static
|-----static_files_here
dajax
Is this about dajax? If you are new to django, I recommend to get away from this stuff. You can just watch the issues list of this project to decide whether you should use it or not. The problem not only about that dajax is bad or good, but that these issues are being made by newbies that don't understand how ajax works, what are csrf tokens and so on.
When I started to learn django, I tried dajax too, but finally I have realized that you should understand how ajax and django works by their own and then try to combine them.

Dynamically add to TEMPLATE_DIRS at runtime with a Django project

For a Django project I'm working on, I need to be able to allow the user to specify the path used in TEMPLATE_DIRS. This is to implement selectable "themes". For example:
TEMPLATE_DIRS = (
os.path.join(WEBSITE_ROOT, 'templates', THEME_NAME).replace('\\', '/'),
os.path.join(WEBSITE_ROOT, 'templates', 'default').replace('\\', '/'),
)
But the THEME_NAME variable should come from the database via the site administration.
Any ideas?
Write a template loader you can point at a theme directory instead.
I've done something like that, pls take a look here https://github.com/ASKBOT/askbot-devel/blob/master/askbot/skins/loaders.py
Besides the template loader you may need means to resolve media specific to your theme. It can be for example a template tag or a filter that takes some base url and adds theme prefix or something like that, also you could make that automatically keep track of media versions. That way that when you refresh .js or other file the client will have to load the latest version.
not sure if it's the same issue as my question theme switching, template and css file layout on a django site
subdirs of templates can be set as context var which is used as parameter for extend template tag

How to make project templates and Satchmo templates co-exist?

I'm working with a Satchmo installation that resides within an existing project. This project has its own templates as well as templates for some of the various apps that are installed. Some of these app-specific templates have their own app_base.html variations that expect to derive form base.html. I'd like to be able to do the same thing with my Satchmo templates and have them reside within my project's base, but also have some additional html added around all of them.
/templates
base.html
index.html
/news
news_base.html (extends base.html and adds news-specific template features)
index.html
detail.html
/store
base.html (overriding Satchmo's base)
This structure works somewhat, but not how I expected. in /store/base.html (Satchmo's base) I've simply replaced everything with a test message. I can see the message, so I know satchmo is loading its base and not the site's base. However, I can't extend my project's base anymore since using:
{% extends "base.html %}
Yields a recursion error since its calling itself and the following simply won't work.
{% extends "../base.html" %}
I realize that I can change my project's base.html to a slightly different name and point all app-specific templates at them, but it seems like a pretty major hack on such a fundamental aspect of the template structure.
Hmm, I didn't think django looked up templates relatively like that.
Kinda crazy hack, but this should work:
/templates/store/base.html extends "global_base.html"
/templates/global_base.html extends "base.html"
Depending on how you have your template structure set up, it might also be a good idea to play with the settings.TEMPLATE_LOADERS variable.
TEMPLATE_LOADERS Default:
('django.template.loaders.filesystem.load_template_source',
'django.template.loaders.app_directories.load_template_source')
A tuple of callables (as strings) that
know how to import templates from
various sources. See The Django
template language: For Python
programmers.
For more information on how this affects the template loading process:
http://docs.djangoproject.com/en/dev/ref/templates/api/#loader-types
From the way you describe your problem, it seems like by commenting out the "app_directories.load_template_source" file line, you might be able to better find a way to accomplish what you're doing.
django.template.loaders.app_directories.load_template_source
Loads templates from Django apps on
the filesystem. For each app in
INSTALLED_APPS, the loader looks for a
templates subdirectory. If the
directory exists, Django looks for
templates in there.
This means you can store templates
with your individual apps. This also
makes it easy to distribute Django
apps with default templates.
For example, for this setting:
INSTALLED_APPS = ('myproject.polls',
'myproject.music') ...then
get_template('foo.html') will look for
templates in these directories, in
this order:
/path/to/myproject/polls/templates/foo.html
/path/to/myproject/music/templates/foo.html
Note that the loader performs an
optimization when it is first
imported: It caches a list of which
INSTALLED_APPS packages have a
templates subdirectory.
This loader is enabled by default.
I just had this same problem. It looks like the satchmo developers planned for this by putting an "empty" base in the shop template directory. While this may not be relevant to you anymore, I would have like to have seen this here.
You can make a "shop" directory in your template directory and copy the main satchmo base.html to that directory.
This worked for me.