I have a project with 2 apps
project/
blog/
templates/
index.html
polls/
templates/
index.html
project/
templates/
base.html
index.html
Now i want that the two apps extends the projects base.html. Is this the way to go? how it is possible and are there better solutions?
There is already an question which is handling this question, but it's only worth mentioning if you dont use split directories:
Django project base template
tl;dr: I want to use split directories and want to know how to extend a base template from multiple apps without copying it to every app
In current Django (1.10) TEMPLATE_DIRS is deprecated, so:
Add a templates directory at the project root,
In settings.py find TEMPLATES -> DIRS and add it like this:
TEMPLATES = [
{
...
'DIRS': [(os.path.join(BASE_DIR, 'templates')),],
...
}
Add a base.html to that directory.
Extend it wherever you want using {% extends 'base.html' %}
Add a templates directory at the project root, and add it to your TEMPLATE_DIRS setting.
Add a base.html to that directory.
Extend it wherever you want using {% extends 'base.html' %}
For Django versions above 1.8 the upgrade doc suggests the vanilla settings (for most non-advanced django tangoers like me) be added to your settings.py:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [(os.path.join(BASE_DIR, 'my_Templates_Directory')),],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
# Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this
# list if you haven't customized them:
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Both BACKEND and OPTIONS were required, otherwise I had errors relating to 'INVALID BACKEND' and 'django.contrib.auth.context_processors.auth' must be in TEMPLATES'.
Related
I'm using django-invitations to manage user invitation.
I can't find where I should put the template files email_invite_message.txt and email_invite_subject.txt
Here they talk about
Override email_invite_message.txt in django-invitations/invitations/templates/invitations/email/.
You can do this by creating the file in the same directory path in your project.
or
Yeah, if this isn't clear, you can create an .html file in your project at {projectroot}/{app}/templates/invitations/email/email_invite_message.html and it will override the default template.
But the first one didn't work for me and I can't figure out what {app} should be.
You can override any third-party application templates by creating replacement files in your project’s templates directory as indicated in the docs here.
In your settings.py file edit the TEMPLATES var, specifically the 'DIRS' key
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
...
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR + '/core/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',
],
},
},
]
let's suppose you have an app named core, edit the settings as in the previous example and put the new files in this way (for this particular app):
core/
/templates
/invitations
/email
email_invite_message.html
email_invite_subject.html
__init__.py
admin.py
apps.py
models.py
tests.py
i'm using Django 1.10 and i want to add the allauth's app for login, signin, etc, to my website. I've installed allauth from pip, and tried to put the templates from allauth repository inside my templates folder and call them but i don't know how to make it work.
The correct answer can be found here: https://stackoverflow.com/a/31282443/4992248
Create yourproject/templates/allauth/account/ and paste here all templates you need to edit from /myproject/Lib/site-packages/allauth/templates/account.
If you need to make changes for socialaccount templates, create also yourproject/templates/allauth/socialaccount/
Edit 'DIRS' in settings.py like 'DIRS': [os.path.join(BASE_DIR, 'templates'), os.path.join(BASE_DIR, 'templates', 'allauth')],
In the end it should look somethink like this:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates'), os.path.join(BASE_DIR, 'templates', 'allauth')],
'APP_DIRS': True,
'OPTIONS': {
'debug': False,
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.template.context_processors.media',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
You never should do any code changes at /Lib/site-packages/*, because all changes are lost once a package is updated.
This worked for me using Django 2.1.7 and django-allauth 0.39.1:
In the folder yourapp/templates/ create a folder named account so at the end the structure is yourapp/templates/account/ and add all templates that you want to override like login.html or signup.html.
In settings.py my Template Dirs remain the same
'DIRS': [os.path.join(BASE_DIR, 'templates')],
It seems that the documentation of the module is out of date. For Django 1.10 you should do the following:
download the module with pip
add the following to INSTALLED_APPS(/settings.py file)
'django.contrib.sites', # first place
'allauth', # after your modules declarations
'allauth.account',
'allauth.socialaccount',
add the backends declarations and another stuff needed by allauth
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'allauth.account.auth_backends.AuthenticationBackend',
)
SITE_ID = 1
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = True
seems that for django 1.10 is not needed to modify TEMPLATES section (django-allauth==0.28.0). You can verify the modules versions using the "pip freeze" command.
create an artificial module to override the templates; for example, my project is named irj_app and I've add a new application called _shared, then i have the following structure, and add it to INSTALLED_APPS before 'allauth' declarations :
irj_app / _shared
i've created a templates directory inside "_shared" folder and i've added a file called "base.html" that overrides the allauth template. what i'd found is that django-allauth creates a template that overrides the layout that you've made before, then you need to intercept the django-allauth templates to change this behavior. Also you can override any template of this authentication mechanism. For example i have:
irj_app / _shared / templates / base.html
irj_app / _shared / templates / account / base.html
irj_app / _shared / templates / account / signup.html
irj_app / _shared / templates / _shared / adminlte-template / ... (template for other modules)
hope it helps
Try This:
Create account directory in your app's template dir so that it looks like below
yourppname/templates/account
and files
yourppname/templates/account/login.html
yourppname/templates/account/signup.html
and add below to your TEMPLATE DIRS Remember to change yourappname to your app's name
os.path.join(BASE_DIR, 'yourappname', 'templates')
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'yourappname', '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',
],
},
},
]
Like many have already told here, all we have to do is bring the account,openid and socialaccount folders from the templates folder of allauth into the templates folder of our project folder.
But one thing to keep in mind while adding the
'DIRS': [os.path.join(BASE_DIR, 'project_name','templates')]
to the setting is that, the BASE_DIR in django points to the directory where manage.py is stored. And it is at this level we have our project folder and our templates folder within the project. So we need to add our 'project_name' and then 'templates' to the DIRS with os.path.join
I use django 3.0.4 with django-allauth 0.41.0
Add folder templates in your project directory.
Inside the folder templates add another folder with the app_name, in the case of the template login.html you'll create a folder accounts
so the full path will be
/project_name/templates/accounts/login.html
my TEMPLATE Dirs in settings.py remain the same
'DIRS': [os.path.join(BASE_DIR, 'templates')]
django-allauth doc templates
Allauth templates can be overridden just like the normal template overriding methods.
Set template directory
TEMPLATE_DIRS = (
os.path.join(BASE_DIR,'templates'), os.path.join(BASE_DIR,'templates'))
Your template directory will be in project directory. Go inside your template directory and create a directory named allauth, inside allauth create a template directory and inside that create a directory accounts
Create html files with same name as allauth templates. Refer to allauth github repository for more info on template names.
In django-allauth==0.36.0
let's say you wanna customize the login page.
don't need to change TEMPLATES setting
just create a folder named account in your project templates folder then:
clone the project
git clone https://github.com/pennersr/django-allauth
cd django-allauth/allauth/templates/account
Copy base.html and login.html to the created account folder
I tried, it works.
Official Link
Well, i was just able to do it.
I didn't know where these templates were but i found that, in my case (i'm using virtual env):
Envs/myproject/Lib/site-packages/allauth/templates
i modified the base.html and added my static folder with all my bootstrap stuff and jquery to the settings in the file:
app_settings.py
and added this.
...
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
And that's all.
I don't know if this is the propper way to do it but if someone have a better answer please post it.
I'm currently overriding change_form.html in my app by dropping it in:
myproject/myapp/templates/admin/change_form.html
That works fine but I really only want to override the change form for the User model, and nothing else. It doesn't seem to work if I drop it in:
myproject/myapp/templates/admin/user/change_form.html
I'm guessing that's because the User model isn't from my app?
What's the cleanest way of overriding change_list.html for a specific model in some other app (namely, the django.contrib.auth app)?
Relevant snippets from settings.py:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, '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',
'unicorn.context_processors.site_url',
'unicorn.context_processors.consultant_data',
'unicorn.context_processors.branding',
],
'builtins': ['tracking.templatetags.tracking_extras'],
'loaders': [
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
],
},
},
]
looks like you need to add your application name to the full path for the template, so it should be
myproject/myapp/templates/admin/myapp/user/change_form.html
settings.py
TEMPLATES = [
{
'BACKEND': ...,
'DIRS': [
os.path.join(BASE_DIR, 'templates'),
],
...
}
]
Place admin/auth/user/change_form.html in project's templates directory.
Overriding admin templates.
for Django 3.2+
first you need to create a similar admin template structure directory in your project which is:
- project_dir
- app
- templates/admin/ <---
- venv
and then copy the change_form.html
from venv/lib/python[ver]/site-packages/dajngo/contrib/admin/templates/
into: /templates/admin/change_form.html
wich is the template folder in your project
this assuming if you using virtualenv
and then set settings.py to:
import os
...
TEMPLATES = [
{
...
'DIRS': [os.path.join(BASE_DIR, 'templates/')],
'APP_DIRS': True,
...
and then you can modify the /templates/admin/change_form.html you already copy,
for example you only want show some text only for user model, you can do something like this:
look for line: {% block field_sets %} and below that put:
{% if opts.model_name == "user" %} Put Your Text Here {% endif %}
so it's looks like this:
{% block field_sets %}
{% if opts.model_name == "user" %} Put Your Text Here {% endif %}
You can replace the user with any model you want.
4 years late, but anyone looking for an answer--
If you installed Grappelli package like me, your issue can be solved by going to python/lib/site-packages/grappelli and looking for the change_form.html there. This package overrides my custom template so I made changes to the grappelli file.
I am following part 2 of the Django tutorial. I am trying to override an admin template (base_site.html)
I copied the file from the django/contrib/admin/templates to mytemplates/admin/base_site.html
I also updated settings.py:
#Base Directory
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
#Template directories
TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'mytemplates'),)
I tried putting the mytemplates folder in the root of the project folder as well as in the mysite folder with no luck. Any pointers would be great!
EDITED PREVIOUS USER RESPONSE -- THIS WORKS:
I think your relative path to the templates directory is wrong.
If you follow these steps it should work: (I tested it myself)
Put the mytemplates dir side by side with the manage.py file
project
-app1
-app2
-mytemplates
-admin
-base_site.html
-manage.py
Change the TEMPLATE_DIRS to:
TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'mytemplates'),)
Make sure the order of the template loader is:
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
#YardenST's answer almost worked for me. I guess it's a matter of configuration.
In case you run into trouble, I suggest you use this line:
TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'mytemplates'),)
Next, put a breakpoint to show the actual outcome, or alternatively use print TEMPLATE_DIRS.
That's where you should place the templates you want to override.
#kat-russo, thx ;)
I tried to setup admin templates according to docs
project_name
-app1
-app2
-project_name //main folder -> settings.py , urls.py, wsgi.py
-templates
-admin
-project_name
base.html
without success, but
-templates
-admin
base.html
works for me.
my config (Django 1.10.4 w/Django CMS 3.4.1)
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',
'sekizai.context_processors.sekizai',
'cms.context_processors.cms_settings',
],
},
},
]
You can override all templates.
Create an admin directory in templates and add the files.
The all files.
https://github.com/django/django/tree/master/django/contrib/admin/templates/admin
I'm attempting to get the Django development server to load a template with the following settings but it's throwing the error
TemplateDoesNotExist at /
homepage/index.html
Below are the files that I've edited to try to get this to work
blog/blog/settings.py - (Cut the portion pertaining to this question)
import os
TEMPLATE_DIRS = (
os.path.join( os.path.dirname(__file__), 'templates' ),
)
blog/apps/homepage/views.py
from django.shortcuts import render_to_response
def index(request):
return render_to_response('homepage/index.html')
Any thoughts about how to fix this?
By default Django uses two template loaders to locate templates:
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
First the filesystem loader checks all dirs in TEMPLATE_DIRS to see if it can find the named template. If that fails the app_directories loader will look in the /templates/ dir in the current app for the named template. This way you can ship default templates with reusable apps that can easily be overridden.
In your case Django will look for the template here:
blog/blog/templates/homepage/index.html
blog/apps/homepage/templates/homepage/index.html
You give a wrong direction to your TEMPLATE_DIRS. The settings.py file is in package blog in project blog, but your templates folder is in blog project, not in blog package. You must give the absolute directory of your project and join templates with it.
in django 1.10, navigate to path/to/settings.py in your parent project directory, look for:
TEMPLATES = [.....] and specify the path/to/project_directory in the DIR: option
for example (in my own case):
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
'/xampp/htdocs/advisory_portal'
],
'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',
],
},
},
]