I'm trying to create base.html to extend it from my apps.
My structure:
ROOT(pyshop)
polls
templates
polls
index.html (contains {% extends "base.html" %})
pyshop
templates
base.html
But it can't find base.html
Template-loader postmortem
Django tried loading these templates, in this order:
Using engine django:
django.template.loaders.app_directories.Loader: /home/sz/Projects/pyshop/polls/templates/pyshop/base.html (Source does not exist)
django.template.loaders.app_directories.Loader: /home/sz/Projects/pyshop/venv/lib/python3.5/site-packages/django/contrib/admin/templates/pyshop/base.html (Source does not exist)
django.template.loaders.app_directories.Loader: /home/sz/Projects/pyshop/venv/lib/python3.5/site-packages/django/contrib/auth/templates/pyshop/base.html (Source does not exist)
Any suggestions?
Your pyshop/pyshop/templates directory will not be searched by the app directories loader, because it is not an app. The usual approach is to add this directory to the DIRS list.
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'pyshop', 'templates'),]
...
}
]
Secondly, the traceback makes it looks as if you are doing {% extends "pyshop/base.html" %}, not {% extends "base.html" %} as in your question. If you have {% extends "base.html" %}, then you will need to move your base.html template to pyshop/pyshop/templates/pyshop/base.html.
Related
Hi I have been trying to customize my admin page and I have some application specific admin pages that require custom javascript and css. I would like to have different base_site.html within the template/admin/ of each app including the required javascript and css. The thing is that only the changes of the base_site.html of the first registered app (inside the settings.py file) are shown.
Is my approach of customizing base_site.html for each app correct? if yes, how can I get it to work?
How to include css and js only in some admin pages?
Thank you.
-app1
-templates
-admin
-base_site.html
-app2
-templates
-admin
-base_site.html
-app3
-templates
-admin
-base_site.html
-manage.py
If you just want to add some custom javascript and css to your admin you'd better use ModelAdmin asset definitions. See django docs for more. Something like this:
class ArticleAdmin(admin.ModelAdmin):
class Media:
css = {
"all": ("my_styles.css",)
}
js = ("my_code.js",)
As for base_site.html, you will not be able to override it for each application, it is general template not application specific template. But anyways, you could override/extend change_form.html and change_list.html templates, based on each application or even for each model. And tree should be as follows:
-app1
-templates
-admin
-app1
-change_form.html
-change_list.html
And if you use extension rather than overriding you may access header using extrahead and extrastyle blocks.
/app1/templates/admin/app1/change_form.html
{% extends "admin/change_form.html" %}
{% block extrahead %}
{{ block.super }}
... your code here ...
{% endblock %}
I am having trouble setting up a template (under app directory) to extend a base.html that is in the root/templates/jinja2 directory
settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.jinja2.Jinja2',
'DIRS': [
os.path.join(BASE_DIR, 'templates/jinja2')
],
'APP_DIRS': True,
...
},
}
]
folder structure:
apps
|---app1
|---templates
|---jinja2
|---listing.html
|---templates
|---jinja2
|---base.html
listing.html
{% extends "base.html" %}
...
The error I am getting when I pull listing.html:
TemplateDoesNotExist at ...
base.html
Django tried loading these templates, in this order:
Using engine django:
django.template.loaders.app_directories.Loader: /webapps/pickup/env/lib/python3.7/site-packages/django/contrib/admin/templates/base.html (Source does not exist)
django.template.loaders.app_directories.Loader: /webapps/pickup/env/lib/python3.7/site-packages/django/contrib/auth/templates/base.html (Source does not exist)
django.template.loaders.app_directories.Loader: /webapps/pickup/src/apps/listing/templates/base.html (Source does not exist)
What is the right way to extend to a base template in the root template folder? I am using Django 3.0.5
Make your folder structure proper
apps
|---app1
|---templates
|---app1
|---listing.html
|---base.html
APP_DIRS means U can use templates folder in app what U've registered in settings.
To specify custom path U need to add NAME parameter.
Or just try to move listing.html in app1/templates/app1/
I have two apps. Both have different base.html templates that index.html extends from. The index.html is different though on each app.
But for some reason it only extends from the same app with base.html? How is this possible?
This is how it looks in both of my my index.html templates:
{% extends 'base.html' %}
How is your template/ directory structure set up? If an index.html template extends from base.html, Django will choose whatever base.html is in your root template directory.
Solution:
Either rename one of your base.html templates to something like base2.html and put it in templates/ alongside base1.html, or create new directories in templates/ to put the base.html files into.
For solution A, make sure you change {% extends base.html %} to {% extends base2.html %} in the appropriate index.html template.
For solution B, your base.html files would keep the same name, but be in different directories. So one is in say templates/base1/base.html and the other is in templates/base2/base.html. Your index.html files would extend like {% extends base1/base.html %} and {% extends base2/base.html %}. Note that all extension paths are relative to the root of your chosen template directory.
IMO solution B is better as it separates the code for each template base into different, explicitly named folders. Better organization/flexibility and less confusion for you in the future.
I have two apps, consisting of adminApp and mobileApp. Both have their own template directory and totally seperated. Unfortunately django keeps looking in the wrong directory when i eg. use extend, it looks into the first template directory according to the order in INSTALLED_APPS:
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
INSTALLED_APPS = (
...
'adminApp',
'mobileApp',
...
)
My directory structure is:
adminApp/
templates/
base.html
mobileApp/
templates/
base.html
So basically what happens is that when i have a file such as mobileApp/templates/pages/index.html with a {% extends "base.html" %} it uses adminApp/templates/base.html instead of its own.
How can i avoid this and keep them separated?
Your apps don't follow the Django conventions for template directories. The app name should be repeated to avoid this issue:
adminApp/
templates/
adminApp/
base.html
mobileApp/
templates/
mobileApp/
base.html
You can then unambiguously specify which template you wish to extend:
{% extends "mobileApp/base.html" %}
While setting up my project and working to keep apps non-dependent, I've hit a snag. I'd like all of the templates from the different apps to have a consistent header and footer. Here's what I'm trying:
myproject/
base/
templates/
header.html
footer.html
app1/
templates/
my_app1_page.html -> want to include 'header.html'
and 'footer.html' from base app
Pretend there are many more apps that want to do this as well. Is this possible and/or the right way to do it?
As long as the apps are in INSTALLED_APPS and the template loader for apps dirs is enabled, you can include any template from another app, i.e.:
{% include "header.html" %}
... since your templates are located directly in the templates dir of your app.
Generally, in order to avoid name clashes it is better to use:
app1/
templates/
app1/
page1.html
page2.html
app2/
templates/
app2/
page1.html
page2.html
And {% include "app1/page1.html" %} or {% include "app2/page1.html" %} ...
But: for keeping a consistent look and feel, it is so much better to use template inheritance rather than inclusion. Template inheritance is one of the really good things of the Django template system, choose inheritance over inclusion whenever it makes sense (most of the time).
My recommendations:
Have a base template for your project ("base.html" is the default convention) with header and footer and a {%block content%} for your main content.
Have your other templates inherit form base.html {% extends "base.html" %} and override the content section
See another response to this question for links to the doc
While you can certainly do that by using the include tag and specifying absolute paths, the proper way to work in Django is by using Template inheritance.
If you start a project with "$ django-admin startproject project" a folder named "project-folder-name" i.e. project/ is created. After adding a few apps and adding the apps in the "settings.py" -> INSTALLED_APPS=[..., app1, app2] and creating a templates folder within the project/ I got structure like this:
project/
project/
templates/
base.html
app1/
templates/
app1/
page1.html
page2.html
app2/
templates/
app2/
page1.html
page2.html
in template app1/template/page1.html I wrote
{% extends 'base.html' %}
and the "TemplateDoesNotExist at /" Error message appeared.
Then I added another App named "core" and added base.html to the template folder (+edit INSTALLED_APPS in settings.py) and i got this structure now:
project/
project/
templates/ (unused)
base.html (not seen)
core/
templates/
base.html
app1/
templates/
app1/
page1.html
page2.html
[...]
Now the error message disappears and the base.html is found with templates/app1/page1.html:
{% extends 'base.html' %}
You can change the folder structure like this:
core/
templates/
core/
base.html
then you need to change the template app1/page1.html to
{% extends 'core/base.html' %}
as well.
As an alternative you can also add "your-project-name" in this explaination "project" into your settings file like this:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'project', # your project name main folder
'core',
'App1',
'App2',
]
And now django finds the project/templates/base.html as well. However I don't know if this solution is recommended.
project/
project/
templates/
base.html (now it is found)
P.S. Thanks (my upvotes aren't counted yet) and comment me if this answer was somehow clear and understandable