Martin Geber
Martin is student at EUFH, Cologne, DE
working casually at DataCollect & EWE
who loves economies, web-technology
and all things J.K. Rowling.
Learn More.
In Django you are able to write websites in a minimum of time with a great result. Some developers, nevertheless, don't care about structuring their source as good as Django does. This will cost time and nerves.
This entry is meant to show how especially freelancers can save time by thinking before programming, what is a good overall rule. ;)
There are developers, who work only on one project. They use Django to be able to concentrate on the real programming and not too boring stuff, like creating comments and so on. I'll call them Idealists, because they (mostly) have an idea, which they want to take into practice. (For them this entry isn't too interesting, I guess.)
The other developer is the one, who write lots of different websites. Often s/he use same applications for different projects. I'll call them Freelancer, because they (mostly) are freelancer. ;)
But one work about Python before we get straight to Django.
media and templates not on project pathIn Django it is common practice to structure a project like this:
/myproject
/app1
/app2
/app3
/media
/templates
settings.py
...
This isn't really good for the reason that the entire project path is saved into PYTHONPATH. The point is that neither media nor templates hold any Python source code. For this reason media and templates should be saved outside the project path. (An example for that can be found later.)
Django follows strongly the DRY-Principle (don't repeat yourself). You should keep that in mind, when you write your own stuff using Django.
As it isn't a dogma to use applications just from within your current project, we are very free in how to create our working places.
I created one Django path on my Linux server /home/httpd/pyhosts/. (Feel free to use any folder you want. But it shouldn't be a folder which is HTTP-accessible. But it should be accessible via an FTP-user.)
/home/httpd/pyhosts
/utils
/utils.templates
/myproject
/myproject.media
/myproject.templates
This example shows on the first hand the ideas from the chapter above and on the other hand you can see that there is additionally to your project myproject another folder on project-level called utils.
Let's say you are writing an application that will most likely be of intrest for more than one project, then it should be placed in the utils folder. (For example a news application, which can be used as news and blog application in a lot of different projects.)
newsAssume this is the new file structure:
/home/httpd/pyhosts
/utils
/news
__init__.py
models.py
views.py
/utils.templates
/news
news_index.html
news_detail.html
category_list.html
category_detail.html
/myproject
settings.py
/myproject.media
/myproject.templates
/news
news_index.html # Replacement of ``utils.templates/news/news_index.html``
It is quite easy now to load the news app into myproject.
Your /home/httpd/pyhosts/myproject/settings.py somehow would look like this:
# settings.py TEMPLATE_DIRS = ( '/home/httpd/pyhosts/myproject.templates', '/home/httpd/pyhosts/utils.templates', ) INSTALLED_APPS = ( 'django.contrib.XXX', 'utils.news', 'myproject.XXX', )
This settings.py now loads the news app from utils. Thanks to the ordering of folders in the TEMPLATE_DIRS variable, myproject.templates overwrites utils.templates. This means that myproject.templates/news/news_index.html replaces utils.templates/news/news_index.html, but all other templates for the news application are loaded from utils.templates.
I guess it is obvious how this works and how powerful it is. Now to get this even better you shouldn't create an "project" calles utils, better use this structure:
/home/httpd/pyhosts
/contrib
/weblog
/entries
__init__.py
models.py
views.py
urls.py
/tags
__init__.py
models.py
views.py
urls.py
/weblog.templates
/entries
/tags
/myproject
settings.py
/myproject.media
/myproject.templates
This structure is very close to the Django internal contrib structure, which was approved by many, many developers. Take a look into the way these applications where created and you'll soon figure that this blog entry didn't reinvent anything, it just points you into the right direction.
I've seen developers copying their applications from one project into the other. Fixing bugs then to copy the same application again.
Some now might say: Where is the individuality? First of all, you can overwrite the templates. Secondly, you are able to require some variables from the settings.py of the importing project.
These variables aren't imported from the project itself, never do something like this:
from myproject import settings
The Django authors already thought of that. Use instead:
from django.conf import settings
You see you have all freedom you need to write individual projects, saving even more time. (Applications like the popular comment_utils should also find their way into your global project.)
I hope you enjoyed reading this entry, in case you still have a question or have a spot I missed, leave a comment.
Why not put /media/ and /templates/ under the application dir? They won't be imported onto the PYTHONPATH unless an init.py file is found.
Python Code is Poetry
© Copyright 1987-2008
Martin Geber
Django | XHTML 1.1 | CSS | Imprint
Kevin Damm commented, on December 22, 2007 at 2:59 a.m.:
With django.template.loaders.app_directories.load_template_source in your template loaders list, you can just store the templates/ directory in the same directory as your application.
This is especially useful if you want to distribute your application -- there's only one directory that needs to be distributed to users, and setup only requires adding the application (assuming the user has the above template loader included already, but it's on by default).
If you are not planning on packaging your application for distribution, and especially if you only have a single django installation, the organization suggested by Martin may be better... but I thought it would be worth mentioning this alternative.