Adding new template folder in Django - django

Say I have the following folder structure
mysite
- mysite
- templates
- books
- templates
- contact
- templates
And I have the following in my settings.py
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),
)
How would I configure the site to look in the templates folder of any sub directory? For example, say I wanted to add another folder to my existing 3 (mysite, books, contact) called "test". I would want the site to automatically know to search in "test/templates".
I am wondering if it is as simple as:
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),
os.path.join(os.path.dirname(__file__), 'mysite/templates').replace('\\','/'),
os.path.join(os.path.dirname(__file__), 'books/templates').replace('\\','/'),
os.path.join(os.path.dirname(__file__), 'contact/templates').replace('\\','/'),
)
To me, that looks like it would point to "/mysite/books/templates" not "/books/templates"

I use something like this:
TEMPLATE_DIRS = (
join(BASE_DIR, 'templates'),
)
And then i put all my templates under the templates folder (which is under the same directory as manage.py). This way i can find all the templates for my project in the same place.
+templates
-app1 templates
-app2 templates
When i need to access a template i just use 'app1/my_template.html'.

Related

Django cannot find images under templates

So I am creating a Django project and put an image on an HTML page. Issue is that the server cannot see it.
This is my folder structure: mysite/app/templates/app/img/pic.png
The HTML page is in: mysite/app/templates
I tried many different scr formats, such as: <img src="../app/img/pic.png"> but it did not work.
You have to set STATICFILES_DIRS to add the folder that you want, or try to put all the static in a folder and reference it in STATICFILES_DIRS, like this:
STATICFILES_DIRS = [
BASE_DIR / "static",
'/var/www/static/',
]
the first url will be <the root of your project>/static
the second url will be that exactly.
For more info you have the docs right here: https://docs.djangoproject.com/en/3.2/howto/static-files/#managing-static-files-e-g-images-javascript-css

Django Templates: How does it decide where to load a template?

I was following the Django Girls Tutorial up to the point where we add the login capabilities and I've gotten to a point where it tries to load from a different template folder than I want.
I have all my blog templates in blog\templates\blog\, etc. and that is where Django is looking for my login.html. However, in the tutorial (and as a result in my folder structures), the path for login.html is: mysite/templates/registration/login.html. So how would I make Django look there?
Sorry if this is a stupid question.
Django will look to your settings.py for how to load templates, and the order in which it should try to load templates. It's likely that you haven't configured django to look for templates in mysite/templates.
There's a setting called TEMPLATE_DIRS which is a list of absolute paths for your template folders. So in your settings.py file, try something like below. Read my comments to see what each line does.
# create a variable that stores the absolute path to your project's root directory
# you might have something like this already defined at the top of your settings.py
BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
# this is the default value for TEMPLATE_LOADERS
# which says to look at the `TEMPLATE_DIRS` variable, and then in each of your app's subdirectories for templates
TEMPLATE_LOADERS = ('django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader')
# the special sauce. tell django to look at the "templates" folder
TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'templates'), )

Templates in shared apps

I have two django projects that share some common apps,
this is my structure:
prj_1
prj_2
common_apps
From prj_1 and prj_2 I use the common apps and I'd like to render these apps with different templates.
How can I do?
Yes, using the following directory structure:
common_apps
app1
templates
app1
# default templates for common app live here
prj_1
templates
app1
# overridden templates for app1 live here (using same file name)
This isn't clearly spelled out in the docs in one place, but your prj_1 templates will override common_apps because the default setting in Django looks like:
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
...and your typical Django settings file will have something like this:
TEMPLATE_DIRS = (
os.path.join(PROJECT_ROOT, 'templates'),
# where PROJECT_ROOT is absolute path to prj_1/
)
...which means when looking for say 'app1/base.html' the filesystem.Loader will get called first and will find any overridden templates in prj_1 so app_directories.Loader won't get called.
Some info here:
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-admin-templates

Tell django to search app's template subfolders

I have the following folder structure for the templates on my django app:
templates/
app/
model1/
model1_form.html
model2/
model2_form.html
Suppose I'm using model1 and a generic ListView, right now it only searches at templates/app/model1_form.html. Is there anyway I can tell django he should also search the app/ subfolders? I don't want to have to set the template name and path manually (template_name="templates/app/model1/model1_form.html").
At settings.py I have:
import os.path
BASE_PATH = os.path.dirname(os.path.dirname(__file__))
TEMPLATE_DIRS = (
BASE_PATH+'/templates/',
)
This is my view:
class HousesListView(ListView):
model = House
context_object_name = "house_list"
Thanks in advance!
The other answers were correct at the time, but for anyone coming across this now, this is how this is done in Django 1.8+
By default, Django now looks in app folders for templates. This is indicated by 'APP_DIRS': True, in the TEMPLATES setting like this:
TEMPLATES = [
{
...
'DIRS': ['templates'],
'APP_DIRS': True,
...
},
]
As the other answers indicate, you should still use appname/templates/appname/model1_form.html to namespace the templates
( more info: https://docs.djangoproject.com/en/1.8/intro/tutorial03/#write-views-that-actually-do-something in the box titled 'template namespacing')
Final check: make sure the app you're using is in the INSTALLED_APPS tuple, as that was the problem I was having.
You need to add django.template.loaders.app_directories.Loader to TEMPLATE_LOADERS (if it's not already).
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
Then, change your folder structure such that you have a "templates" folder in the app directory:
- <project_root>
- app
- templates
- model1
- model2
Or to properly namespace the models so they don't clash with other app names accidentally:
- <project_root>
- app
- templates
- app
- model1
- model2
I think to use templates from subfolders generally you either have to:
Manually give the template path as subdir/template.html
eg. render_to_response('sub/dir/template.html') or template_name='...'
Define all the subfolders in the TEMPLATE_DIRS
eg.
TEMPLATE_DIRS = (
BASE_PATH+'/templates/',
BASE_PATH+'/templates/app',
BASE_PATH+'/templates/app/model1',
)
But because Generic Views except templates to be found in app_name/template.html,
you would have to move your templates to add /path/to/templates/app/model1 to your TEMPLATE_DIRS, and move your templates to templates/your_app/model/your_app/model_template.html, which is little bit awkward.
With Django 2.0, it's not even necessary to change anything in the TEMPLATES variable in settings.py.
The only requirement is to add appname.apps.AppnameConfig (e.g. catalog.apps.CatalogConfig for an app named 'catalog') to the INSTALLED_APPS list, then django will look under appname/templates when it searches for templates.

What am I doing wrong with Django static files?

I am working on writing a Django app for the first time, so bear with me if I'm a little behind on things.
Here is an excerpt from my settings.py:
STATIC_ROOT = os.getcwd().replace('\\','/') + '/static'
STATIC_URL = '/static_files/'
STATICFILES_DIRS = (
os.getcwd().replace('\\','/') + '/static'
)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
Note: I'm hoping that the os.getcwd()... line works. I am pretty sure it's not my problem, but please let me know if this is an issue. It's a placeholder for local dev purposes, so don't worry about it remaining there when I deploy.
My first issue is that template variables don't seem to be working.
An excerpt from my main template file:
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL|default:'/static_files/' }}css/base.css" />
I originally just had {{ STATIC_URL }} in there, but that simply returned nothing, so I tried adding |default:'...'. This did successfully generate the given string in the resulting HTML, but still didn't work, which brings me to my second (and more important, honestly) issue.
I can't get static files to work at all. I have tried several different methods here. I have tried putting absolute and relative paths (in various combinations) in each of the above STATIC_* variables, I have tried using the equivalent MEDIA_URL vars instead, and I have tried putting the following into my urls.py:
urlpatterns = ('',
# ...
(r'^static_files/(?P<path>.*)$',
'serve', {
'document_root': '/path/to/django/dir/static_files/',
'show_indexes': True
}
),
)
(I grabbed the above snippet from http://www.arthurkoziel.com/2008/09/02/handling-static-files-django/.)
Now I should note that I will hopefully be eventually serving up static files from a parallel Apache process once initial dev is completed, but I would still really like to know what I'm doing wrong. I haven't been able to find a decently comprehensive tutorial on static files online or on StackOverflow.
All help is greatly appreciated.
EDIT: In case it is important, I am on Windows 7 using Python 2.7.
One possibility - STATIC_URL won't be filled out in your templates unless you're passing in a RequestContext.
Make sure you have something like this in your views:
return render_to_response(template, context, context_instance=RequestContext(request))
As of Django 1.3 you can also use the new shortcut:
return render(request, template, context)
Also, make sure you have 'django.core.context_processors.static' in your context processors.
EDIT: Possible answer to the second problem, try changing
STATICFILES_DIRS = (
os.getcwd().replace('\\','/') + '/static'
)
to
STATICFILES_DIRS = (
os.getcwd().replace('\\','/') + '/static',
)
EDIT 2: More possible fixes
You can delete STATICFILES_FINDERS. You only have it set to the default, so unless you intend to expand it later on, get rid of it (one less thing to go wrong).
You can also get rid of the urlpatterns entry. Not necessary.
Your STATIC_ROOT is probably incorrect. This should be the place where Django will gather all the static files from across your project (including the directories described in STATICFILES_DIRS) when you move to production.
An example from a typical settings.py of mine:
PROJECT_DIR = os.path.dirname(__file__)
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(PROJECT_DIR, 'static'),
)
STATIC_ROOT = '/var/www/myproject_staticfiles/'
That's it!
If you want to test whether Django is finding and placing your static files correctly, try running
python manage.py collectstatic
In my case, that would go through my project directories, find all the static files, then copy them across to '/var/www/myproject_staticfiles/', where I can host them with apache.
The Django dev server automagically serves static files from within your project folder, so no collect_static is required while in dev. You don't even need to set STATIC_ROOT until you go into production.