Code

Opened 8 years ago

Closed 5 years ago

Last modified 8 months ago

#694 closed enhancement (wontfix)

[patch] TEMPLATE_DIRS should allow project root relative paths

Reported by: nirvdrum Owned by: adrian
Component: Template system Version: master
Severity: normal Keywords:
Cc: sorin, moeffju Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by adrian)

Many people develop their projects on one machine and deploy on another. The two (or more) different computers may not have the same filesystem layout and may not even be running the same OS. As such, it'd be nice if the requirement for absolute paths could be eliminated.

For my current django project, I have something like:

project/
   apps/
   templates/

It'd be nice if the templates directory could be specified relative to the project root.

Attachments (0)

Change History (12)

comment:1 Changed 8 years ago by nirvdrum

It appears that didn't format as well as I had planned. The idea is that project/ is the parent of apps/ and templates/.

comment:2 Changed 8 years ago by adrian

  • Description modified (diff)
  • Resolution set to invalid
  • Status changed from new to closed

(Fixed formatting in the description.)

TEMPLATE_DIRS is a setting, and each of your Django installations should have a separate settings file. This is how you designate different database passwords for different servers, for instance. The solution is to use separate settings files for your multiple environments.

Also, if that doesn't float your boat, you can use the "app_directories" template loader. See http://www.djangoproject.com/documentation/templates_python/#loader-types .

comment:3 Changed 8 years ago by hugo

And one should allways remember that settings files are just python: so you can just use "from basesettings import *" to pull in common settings that are the same accross different projects. Project settings really only need to set what is special for exactly this project.

Another idiom I find quite useful:

import os

TEMPLATE_DIRS = (
    os.path.expanduser('~/project/something/templates'),
)

works quite nice in projects that move to other servers and users when going production, but don't change in their structure itself.

comment:4 Changed 8 years ago by Sune Kirkeby <sune.kirkeby@…>

  • Resolution invalid deleted
  • Status changed from closed to reopened
  • Summary changed from TEMPLATE_DIRS should allow project root relative paths to [patch] TEMPLATE_DIRS should allow project root relative paths

Actually, adrian, that's a really poor excuse for not implementing this feature; if you specify a
relative path in your TEMPLATE_DIRS the only reasonable interpretation is that it's relative
to either your project-root or your settings-file. And, the different settings argument is hardly
relevant, relative TEMPLATE_DIRS are also broken for single-installation projects.

Besides, it's so simple to implement:

--- django/conf/settings.py     (/django/trunk) (revision 3075)
+++ django/conf/settings.py     (/django/patches/project-template_dirs) (revision 3075)
@@ -44,6 +44,21 @@
             setting_value = (setting_value,) # In case the user forgot the comma.
         setattr(me, setting, setting_value)
 
+# TEMPLATE_DIRS are relative to the directory containing the top-level
+# module of DJANGO_SETTINGS_MODULE.
+if '.' in me.SETTINGS_MODULE:
+    name, _ = me.SETTINGS_MODULE.split('.', 1)
+    project_mod = __import__(name, '', '', [''])
+else:
+    project_mod = mod
+project_root = os.path.dirname(project_mod.__file__)
+
+if os.path.isdir(project_root):
+    me.TEMPLATE_DIRS = [
+        os.path.abspath(os.path.join(project_root, os.path.expanduser(path)))
+        for path in me.TEMPLATE_DIRS
+    ]
+
 # save DJANGO_SETTINGS_MODULE in case anyone in the future cares
 me.SETTINGS_MODULE = os.environ.get(ENVIRONMENT_VARIABLE, '')

comment:5 Changed 8 years ago by adrian

  • Resolution set to wontfix
  • Status changed from reopened to closed

Because the settings files are pure Python, you can calculate the relative paths directly in the settings files. I'm marking this (again) as a wontfix.

comment:6 Changed 5 years ago by aljungberg

The posted solution, to have a settings file for every installation location, is insufficient for our needs. That solution creates two distinct problems:

  1. Every developer on the project is forced to have one or more settings files as they check out the project source code into different folders. Or each developer hacks their settings.py file to match their own situation which leads to merge conflicts.
  2. Requiring manual changes between production and test environments increases the risk of problems that only occur during production deployment.

We implemented the alternative solution from adrian's last comment and I will share it here for quick reference for other users who run into this particular limitation.

In settings.py,

import os
PROJECT_PATH = os.path.abspath(os.path.split(__file__)[0])

TEMPLATE_DIRS = (
    os.path.join(PROJECT_PATH, "templates"),
)

If this ticket is revisited in the future it is my opinion that it should be implemented as suggested to promote 'batteries included' and 'keep it simple' philosophies in Django.

comment:7 Changed 5 years ago by sio4

  • Resolution wontfix deleted
  • Status changed from closed to reopened

I'm newbie to django, and this page is the result of one of my few searches about django. It means, IMHO, maybe many newbies can confuse on this issue like me.

my question is: "why we should use relative path for templates directory setting? It is always same in relative(for many cases) but it is different in absolute.(and how many times is it placed on outside of project?) then why we all do add three same lines into settings.py everytime? (import os, project_path=..., os.path.join...)" can I get some reasonable reason?

"app_directories template loader" is not a good solution because the look&feel is site specific rather than application specific. (app_directories template loader is usefull for drop-in applications instead.)

please excuse my poor English. thank you for your consideration.

comment:8 follow-up: Changed 5 years ago by ubernostrum

  • Resolution set to wontfix
  • Status changed from reopened to closed

This was marked "wontfix" by a core developer. If you disagree, start a thread on the django-developers list.

comment:9 Changed 4 years ago by sorin

  • Cc sorin added
  • Version set to SVN

Please reconsider this issue, it is #1 having more than 100 votes on http://stackoverflow.com/questions/550632/favorite-django-tips-features

Implementing this will improve user experience and simplify deployment.

The fact that people can change the code is not an excuse not to do the right thing.

comment:10 in reply to: ↑ 8 Changed 4 years ago by ubernostrum

Quoting myself: If you disagree, start a thread on the django-developers list.

So if you feel strongly about this, you know what to do.

comment:11 Changed 10 months ago by moeffju

  • Cc moeffju added
  • Easy pickings unset
  • UI/UX unset

comment:12 Changed 8 months ago by anonymous

Has this been fixed?

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.