I get this when trying to access an existing template:
Template-loader postmortem
Django tried loading these templates, in this order:
Using loader django.template.loaders.filesystem.Loader:
Using loader django.template.loaders.app_directories.Loader:
/blah-blah/venv3.4/lib/python3.4/site-packages/django/contrib/admin/templates/polymer.html (File does not exist)
/blah-blah/venv3.4/lib/python3.4/site-packages/django/contrib/auth/templates/polymer.html (File does not exist)
This is a brand new project and, for lack of a better place, I have place my templates in the top dir:
├── manage.py
├── polymertest
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── views.py
│ └── wsgi.py
├── static
│ ├── bower_components
│ └── polymer
└── templates
└── polymer.html
I am able to solve the problem by adding os.path.join(BASE_DIR, 'templates') to settings.TEMPLATES['DIRS']
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',
],
},
},
]
This does look suspicious to me, but according to the documentation, this is expected behavior: you need to configure DIRS. My question is then:
Where should I place my templates in a brand new Django project so that they are found by the filesystem.Loader without configuration? Or is this not possible at all?
This seems like a common use case to me: create a project, add a template, add a view and boom, serve it! I am surprised that it is not automatically covered.
For a settings file created with ./manage.py startproject, the APP_DIRS option is True. That means that when you create an app, any templates in that app's template directory will be found.
The DIRS option defaults to an empty list. That means that apart from app template directories, there are not any template directory that always work without configuration changes.
Setting 'DIRS': [os.path.join(BASE_DIR, 'templates')], is a common approach, and it's suggested in the documentation.
Related
I currently have the following in settings.py:
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
#add app-specific static directory
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'project/static'),
os.path.join(BASE_DIR, 'project/apps/blog/static/'),
os.path.join(BASE_DIR, 'project/apps/users/static/'),
os.path.join(BASE_DIR, 'project/apps/comments/static/'),
os.path.join(BASE_DIR, 'project/apps/categories/static/'),
)
Should I be doing this in one line? Thanks very much.
You can add custom static file finder that would sort you out, but generally if you have /static folder inside of the app it should be discovered by
django.contrib.staticfiles.finders.AppDirectoriesFinder
as documented
The default will find files stored in the STATICFILES_DIRS setting
(using django.contrib.staticfiles.finders.FileSystemFinder) and in a
static subdirectory of each app (using
django.contrib.staticfiles.finders.AppDirectoriesFinder). If multiple
files with the same name are present, the first file that is found will be
used
Source
A better practice is to put all your static files in the same folder in your root directory instead of each app:
# ...
├── app1
├── app2
├── project
├── manage.py
├── media
├── requirements.txt
├── static
│ ├── css
│ ├── icons
│ ├── img
│ ├── js
│ └── vendor
Then in your settings.py assign this variable:
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'), ]
staticfiles_dirs sets the directory and tells Django where to look up for your static files, in this example, our folder is named 'static' in our root directory, os.path.join will join the base directory(root) with static.
BTW STATIC_ROOT is usually used in a production environment, when you run 'collectstatic` command, all static files including your 3rd party apps will be copied to this 'staticfiles' folder.
Also, you can put templates of each app into the same folder in a similar way:
# root
└── templates
├── app1
├── app2
├── app3
├── base.html
└── index.html
And in your settings.py, add the directory of 'templates' folder.
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': { # ...
],
},
},
]
Personally, I think this would be much cleaner.
You can reference my project for the file structure:
here
I would like to have a header/footer that follows throughout the entire site. Currently, I have a base.html file sitting within an app (project/app1/templates/app/base.html) and would like to apply an html template that I can use across the entire site. Is this possible or are templates only referanceable within the app templates folder? Can I have a template sitting in a higher directory such as project/template/base.html or project/base.html and call that so I don't have to copy and paste the same template into each app templates folder?
We can use a root "templates" directory for the project.
settings.py
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
# ... some options here ...
},
},
]
project structure
└── MY_PROJECT
└── BASE_DIR
├── my_proj
│ └── settings.py
├── manage.py
└── templates
For more information Read: https://learnbatta.com/blog/understanding-django-project-structure-26/
I have a Django project that is going to use React as the frontend. The project structure is as follows:
ProjectName/
├── api/
│ └── otherapp1/
│ └── otherapp2/
│ └── api/
│ └── views.py (will contain the method for loading react page)
│ └── settings.py
│ └── manage.py
└── frontend/
└── public/
└── index.html (react root page)
How can I load the index.html page with Django so I can use django for authentication and cookie/session management? I can't figure out how to configure the template/template dirs properly since it's outside the root folder for the django part of the project.
The boilerplate I was using is here
It might be relevant to note that since it is a docker project, there are 3 containers. One for the database, one for django, and one for the frontend. BASE_DIR in my django project resolves to /app/api. It might be that I need to access a directory in another container, but if I can't do that, then how should I go about linking Django to my React app?
Update the TEMPLATE config in settings(api/api/settings.py):
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, '../frontend/public')],
'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 Django would look for template files in frontend/public directory
I am newly learning Django and was following the Learn Django 1.11 Tutorial.
Here is my current project tree:
├── manage.py
├── muypicky
│ ├── __init__.py
│ ├── old_settings.py
│ ├── settings
│ │ ├── base.py # Contains the settings (like shown in the tutorial)
│ │ ├── __init__.py
│ ├── urls.py
│ └── wsgi.py
├── requirements.txt
├── restaurants
└── templates # Templates Folder
└── index.html
I am trying to add the path to the tempelates folder in the settings folder. But the error shown
django.template.loaders.filesystem.Loader: .../muypicky/templates/index.html (Source does not exist)
Current setting.py file
TEMPLATES = [{
'DIRS': [os.path.join(BASE_DIR, 'templates')],
},]
Looking at the error, the file path is wrong because it goes into /muypicky/tempelates which is incorrect. So how do I get to root folder and then into tempelates folder with the given file tree in setting.py (base.py).
Any further queries, just ask and many thanks in anticipation.
Solution:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
and
TEMPLATES = [{'DIRS': [
os.path.join(BASE_DIR, 'templates')
],},]
Addition of os.path.dirname() was wrapped to go back one folder
settings.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads')
MEDIA_URL = '/uploads/'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [MEDIA_ROOT + '/'],#other app templates
'APP_DIRS': True,#heremention yourapp/templates
'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',
'django.template.context_processors.media'
],
},
},
]
also can you look at document djano template
I faced similar problem and was able to rectify with this:
TEMPLATES = [{
....
'DIRS': [os.path.join(BASE_DIR, '/templates')],
....
Dev Environment: django 2.2, python 3.6
so i think you need to add / before the 'templates' string...
I also think this changes with django versions as i'm currently working on another project that didn't require the trailing / before the 'templates' string on django 2.1, python 3.6. So i think this is worth trying out good luck
I have been trying to customize Django REST framework's browsable API pages from my application, as shown here, but the children templates seem to be ignored (incidentally, this also happens when trying to extend DRF Docs base template). This is the relevant part of the file tree:
├── <app>
│ ├── templates
│ │ ├── <app>
│ │ │ └── index.html
│ │ ├── rest_framework
│ │ | └── api.html
│ │ └── rest_framework_docs
│ │ └── docs.html
And even though api.html starts with {% extends "rest_framework/base.html" %} the changes made to the relevant code blocks (e.g. bootstrap_theme) are ignored and the default template is shown instead. What am i missing? Most related questions refer to errors in urls.py, but i believe this is not the case
PS: This is on Django 1.9.8
I've been struggling with the same problem for a while and I fixed it by adding the BASE_DIR path to the TEMPLATES dict into settings.py, like this:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
BASE_DIR,
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',
],
},
},
]
Hope this helps, otherwise if you can share more information about your project maybe I can help more ;) (I mean: settings.py, urls, full project structure...).
I know that it might be a bit late, but add the following to your templates settings:
'DIRS': [os.path.join(BASE_DIR, '../templates')]
The whole reasoning for me was the fact that I have put the templates in a different place of the one I referred too.