Standard for application-specific template directories in Django? - django

I guess this is a question related to best practises in Django development.
I'm trying to build a web service with a main page (base.html) that contains multiple apps. I would like to make the apps self-contained, so I've made a templates directory in each app, and would also like to take advantage of the template inheritance feature of Django to make this whole thing as fluid as possible.
Now my concern is, where should I put the base.html in my project, so that the system knew where to find it?
Also, what changes should I make in the settings.py file in order for the system to be able to connect the templates? Is there a standard or a known method that takes minimal effort for this sort of arrangement?

You can put the templates folder in the project folder (ie folder contains settings.py).
as #danialroseman said, you just need to update the DIRS in TEMPLATES variable in settings.py. Let the project folder be myproject(ie folder contains settings.py)::
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
### ADD YOUR DIRECTORY HERE LIKE SO:
'DIRS': [ os.path.join(BASE_DIR,'myproject', 'templates')],
...
you dont need to create a seperate app.

One common design pattern that I have both seen and used is to have a centralized "app" as a part of your project that contains all the shared "stuff" you care to use in other applications. So you might have the following directory structure:
base/
static/
css/
common.css
js/
common.js
templates/
base.html
myapp1/
urls.py
views.py
templates/
...
myapp2/
urls.py
views.py
templates/
...
myproject/
settings.py
urls.py
Now you just include the "base" application just like any other, and you put shared stuff inside it. Other applications can refer to templates that live there, and can include any common libraries that you may want to share.
In settings.py:
INSTALLED_APPS = ['base', 'myapp1', 'myapp2']

There's no need for a central app for this. The TEMPLATES setting also includes an option for DIRS, which is a list of directories that will always be searched. So you can set this to an appropriate directory - eg os.path.join(BASE_DIR, 'templates') and put your non-app-specific templates such as base.html there.

Related

Why did I get Template does not exist error, though it appears Django offers flexibility with respect to folder structure?

I have read several posts here where people discussed their preferred directory structure to keep various files of their Django project. But I get a file-does-not-exist error if I put my templates in the inner my_project folder instead of the outer my_project folder which contains the manage.py file. Is there some config file that specifies the default location of the templates (and other files)?can you please help me with the command change if I put templates in the inner (sub) folder? I just began my first Django project and would appreciate your help.
Ok, django looks for your templates at default places. I recommend you put your html files there (as a beginner).
Default places are:
- my_site_project/
-- templates/
--- base.html
--- navbar.html
--- footer.html
-- my_app1/
--- templates/
---- my_app1/
----- index_app1.html
----- about_app1.html
-- manage.py
If you put a general templates/ folder inside your project, same folder as your manage.py, those templates will be pulled.
If you want app specific templates the convention is to put a folder inside your app, again called templates/. This can lead to overlap if you put index.html inside your app-templates and an index.html inside your general templates/. Therefore you need to namespace the templates of your app. Create the app; create a folder called templates/ inside it; inside just created templates/folder you create another folder called my_app1; in that folder create your .html files.
Read the tutorial here. It is probably easier to understand than my jibberish. It is the official django tutorial.
A part of it:
First, create a directory called templates in your polls directory.
Django will look for templates in there.
Your project’s TEMPLATES setting describes how Django will load and
render templates. The default settings file configures a
DjangoTemplates backend whose APP_DIRS option is set to True. By
convention DjangoTemplates looks for a “templates” subdirectory in
each of the INSTALLED_APPS.
You can, in your settings.py via DIRS, specify where django looks for your templates. Although as a beginner I do not know why you should not stick to the conventions first.

Move customized django-allauth templates to directory other than 'account'

I set up django-allauth correctly following the project's documentation. I wanted to override the look and feel of the django-allauth templates so I went to the project github and downloaded the django-allauth templates folder into my accountsapp/templates directory.
My problem is that django-allauth will only look for its templates in the templates/account folder.
I want to put my templates in the templates/allauth/account folder to help keep MY template files separate from django-allauth's template files.
When I do this, django-allauth is unable to find the templates that I customized.
Here is my project structure:
projectfolder/
accountsapp/
templates/
projectsettings/
settings.py
manage.py
What I've tried:
Setting my TEMPLATES 'DIRS' to this
'DIRS': [ os.path.join(os.path.dirname(BASE_DIR), 'accountsapp', 'templates', 'allauth'), ],
With BASE_DIR being this: BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))).
This works, but I'm not sure that this is the best practice/solution to my problem.
If you put your templates in projectfolder/accountsapp/templates/, then the app directories loader will find them, as long as you have 'APP_DIRS': True in your template settings.
However, if you move the templates into the projectfolder/accountsapp/templates/allauth subfolder, then the app directories loader will not find them, so you will have to add the directory to DIRS as you have already done.

Should my Django site's main page be an app?

I have finished reading the Django official tutorial which teaches how to create a simple polls app, which is the way they chose to teach beginners the Django basics.
My question is, now that I know how to make a simple app and want to create my own website (using Django), should the main (front) page of my website, be an app as well? If so, how do people usually call it and configure it? I mean, it should do nothing but render a html template, so why make it so complicated? If not, where do I put all the static files and how do I reference them? I am a bit confused and could use your help. Maybe I misunderstood Django's main use?
You can create your templates and static files in the root project folder where your manage.py file lives. In the root folder create the following folders:
templates (for HTML)
static (for CSS, JS and images)
In your settings.py file, make these variables look like this:
TEMPLATES = [
{
...
'DIRS': [
os.path.join(BASE_DIR, 'templates'),
],
...
},
]
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
Note: STATICFILES_DIRS variable is initially not present in the settings.py file, but you can add that by your own. Django, by default, finds static files in the static directory of each app. If you want Django to read the static directory you created in the project root, you need to add this variable. Django official documentation reference: https://docs.djangoproject.com/en/1.10/ref/settings/#std:setting-STATICFILES_DIRS
To render these templates you can create views.py in the directory where your settings.py file lives and add the route in urls.py in the same folder.
This is one of the several ways to achieve what you want. Hope you won't need to plug these templates (eg, your home page) to or say use these templates in any other project, otherwise do as Timmy suggested in the comment on your post.
I usually start with 3 apps (call them whatever you want):
layout - basic layout: some common static files and a basic-template (other templates extend this one, main purpose is to
include a common html <head> ). Also contains the home-page and some other simple pages.
config - contains the project settings / configuration, and the main urls.py (and in my case also wsgi.py)
myapp - the actual app I want to create.
This nicely separates functionalities. Often I can just re-use the base app for other projects.
$ ./manage.py startproject config
$ ./manage.py startapp layout
$ ./manage.py startapp myapp

Changing Admin Templates - Django tutorial 2

This question was answered more or less here but it didn't work to me and as far I can see more people have the same problem.
In my settings.py I have this lines:
#TEMPLATE_DIRS = [os.path.join(BASE_DIR,'..', 'templates'),]
TEMPLATE_DIRS = ("/root/GODJANGO/thedjango/django_project",)
The comented line didn't work. It works if I write the full path but It's not professional and I don't wanna have problems when I three months later I migrate my server because I will not remember this thing.
Can anybody tell me how to write My Path correctly ("dynamically, I mean")
Please tell me where is the best directory to put my templates folder and also my admin templates folder
If you have the following project layout:
manage.py
myproject/
settings.py
urls.py
wsgi.py
templates/
admin/
app1/
app2/
Then you can dynamically set your template directory by putting the following in your settings.py:
...
SETTINGS_PATH = os.path.abspath(os.path.dirname(__file__))
TEMPLATE_DIRS = (
os.path.join(SETTINGS_PATH, "templates")
)
...
if your template folder is in the parent folder to the settings.py you will need something like:
...
SETTINGS_PATH = os.path.abspath(os.path.dirname(__file__))
PROJECT_FOLDER = (os.path.split(SETTINGS_PATH))[0] # get the parent directory
TEMPLATE_DIRS = (
os.path.join(PROJECT_FOLDER, "templates")
)
...
As you can see, we are manually traversing the file tree to find where the templates folder is and assigning it dynamically.
The best place for your templates folder depends on your project layout (< 1.4 or >= 1.4) but it would be probably safest to say that it should be alongside your settings.py file. Your admin template folder will go inside your base templates folder: templates/admin/.
What are you trying to do with this paramater ".." in the commented line?
if it is means parent directory you can use os.path.dirname(BASE_DIR)
Second part:
It depends you or team work with; i love to keep templates directory in every app's directory (and if you do like this you don't need to define TEMPLATE_DIRS). I mean if i have templates of news app, they goes ../news/templates/. But this time my friend (front-end developer) says i cant find them, can we put all of them in one place?
so i put them in one directory with sub directories (../templates/news/). This main templates directory is in main project directory (near the manage.py file). And if you add this main directory to INSTALLED_APPS (because its kind an app) you don't need to define TEMPLATE_DIRS too. And even you can create models.py admin.py files here.
Considering the second part of your question and according to this the safest part for your templates is to create a templates dir under your projects main directory (e.g. blog).
As for the first part i am not sure.

What is the best location to put templates in django project?

What is the best location to put templates in django project?
Placed in <PROJECT>/<APP>/templates/<APP>/template.html for app-specific templates to help with making the app reusable elsewhere.
For general "global" templates I put them in <PROJECT>/templates/template.html
From the Django book, chapter 4:
If you can’t think of an obvious place
to put your templates, we recommend
creating a templates directory within
your Django project (i.e., within the
mysite directory you created in
Chapter 2, if you’ve been following
along with our examples).
This is exactly what I do, and has worked great for me.
My directory structure looks something like this:
/media for all my CSS/JS/images etc
/templates for my templates
/projectname for the main project code (i.e. the Python code)
Following up from Dominic and dlrust,
We use a setuptools source distribution (sdist) to package our django project and apps to deploy in our different environments.
We have found that the templates and static files need to be under the django application directories so that they can be packaged up by setuptools.
For example, our template and static paths look like:
PROJECT/APP/templates/APP/template.html
PROJECT/APP/static/APP/my.js
For this to work, the MANIFEST.in needs to be modified (see http://docs.python.org/distutils/sourcedist.html#the-manifest-in-template)
An example of the MANIFEST.in:
include setup.py
recursive-include PROJECT *.txt *.html *.js
recursive-include PROJECT *.css *.js *.png *.gif *.bmp *.ico *.jpg *.jpeg
Also, you need to confirm in your django settings file that the app_directories loader is in your TEMPLATE_LOADERS. I think it's there by default in django 1.4.
An example of the django settings template loaders:
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
Just in case you are wondering why we use sdists instead of just coping rsync files; it's part of our configuration management workflow where we have a single build tarball that is deployed with PIP unchanged into test, acceptance and production environments.
DJANGO 1.11
add templates folder where the manage.py exist,which is your base directory.
change the DIRS for TEMPLATES as following in your settings.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
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',
],
},
},
]
Now to use the template by using the code ,
def home(request):
return render(request,"index.html",{})
in views.py.
this works completely fine for django 1.11
Django 1.10
TEMPLATE_DIRS is deprecated.
Now we need to use TEMPLATE, introducing in Django 1.8 like this:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
# ... some options here ...
},
},
]
Once you have defined TEMPLATES, you can safely remove ALLOWED_INCLUDE_ROOTS, TEMPLATE_CONTEXT_PROCESSORS, TEMPLATE_DEBUG, TEMPLATE_DIRS, TEMPLATE_LOADERS, and TEMPLATE_STRING_IF_INVALID.
About the best location, Django looking for template like this :
DIRS defines a list of directories where the engine should look for template source files, in search order.
APP_DIRS tells whether the engine should look for templates inside installed applications. Each backend defines a conventional name for the subdirectory inside applications where its templates should be stored.
More information :
https://docs.djangoproject.com/en/1.10/topics/templates/#configuration
This is more a personal choice at the project-level. If you are talking about apps that need to be pluggable, then a templates directory in your app is the place where they go default. But project-wide, it is what works best for you.
I understood TEMPLATE_DIRS requires an absolute path. And I don't like absolute paths in my code.
So this is working well for me, in settings.py:
import os
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(os.path.realpath(__file__)),
"../APPNAME/templates")
)
Previous solution didn't work in my case. I used:
TEMPLATE_DIRS = [ os.path.join(os.path.dirname(os.path.realpath(__file__)),"../myapp/templates") ]
You could also consider having your templates in a database, using django-dbtemplates. It is also setup for caching, and the django-reversion application which helps you keep old versions of your templates around.
It works quite well, but I'd prefer a little more flexibility on the import/sync to/from filesystem side.
[edit: 20 Aug 2018 - this repository is no available, one with the same name is available at https://github.com/jazzband/django-dbtemplates and was updated 8 months ago. I no longer use Django in any meaningful way, so can't vouch for this.]