Friday, January 2, 2009

Configuring Mulitple Django Apps under one Project

Setting the Stage:

I have found Django to be rather daunting to configure and get set up. Being a Django newbie, bear in mind that there may be better ways or more secure ways. Advice from readers is welcome. The extent of my Django experience is that I've been through the Django tutorials. Enough disclaimer.

It took me awhile to draw the connection between my Apache configuration, my settings.py file, my urls.py file, the physical directory structure and the references to those files in code (templates and views).

Getting Started with the Pieces and the Problems:

I went through the tutorial on the Django site. So, I'm going to assume that you did, too. Otherwise, you might find this post quite confusing. As soon as I finished the tutorial, I wanted to try to set up another app for myself. I didn't want to start completely over either. Basically, I wanted to just add another app to my setup so that everything I had already done with the tutorial still worked (that way I could use it for reference), but my new app would work, too.

Identifying the pieces:
  1. settings.py
  2. urls.py
  3. Apache config
  4. physical directory layout
  5. references to templates, within other templates and views
One thing to keep in mind is that when you combine the pieces, they should combine to reveal a full path. Another thing to note is with a PHP set up, the URL you type is can be directly matched to the DocumentRoot and physical file structure. In the case of Django, the URL will be mapped to views, which do not have a physical filesystem structure that matches.

Let's look at some of the pieces. Some of the criteria in coming up with a configuration are that I wanted all of my templates grouped together, all of my apps in the same directory a static directory like a LAMP setup and the admin module should handle all of the apps in this project.

Assuming You have the Django Polls Tutorial Up and Running:

This is my physical filesystem layout. I'm not going to list every file, just the ones that are important for the discussion. Here, admin refers to the builtin Django app, app1 refers to the polls and app2 will refer to my new app:

Show File Tree (+)

I use virtual directories with Apache. I'm not going to going too far into basic Apache configuration, though. Here's the configuration.

Show Apache Config (+)


The relevant parts of the settings.py.

Show Settings.py (+)


The urls.py:


I didn't do anything special in the urls.py files. They are just like the Django tutorial. So, I will refer you to that.

Referencing templates in code:

So far, I'm just working on the templates for my app2 (my new app). And, I only have a base template and one that inherits from it. The point I'd like to make is how Django finds them, not how the templating system works.

As pointed out in the filesystem layout above, my app2 base template is in /usr/local/www/django/prj_1/templates/common/base.html. My template located at /usr/local/www/django/prj_1/templates/app2/index.html, refers to it as such:

{% extends "common/base.html" %}

We're ready now, to put some of this together. But, I'll do it all at once in the next section.


Putting it All Together:

Now, we have make sense of where everything lives, Now, it's time to see how you tell Django to find everything. I will list each thing that need to be located, then how it is resolved.
  1. the settings.py and urls.py
  2. the static pages
  3. the views
  4. the templates
  5. the apps
settings.py and urls.py

These are set by the PythonPath directive in Apache. The Django documentation explains that you have point it to the parent directory. I have two paths listed in my PythonPath, I suspect only one of them is necessary, but I haven't confirmed that yet.

static pages

This is set by the DocumentRoot directive in Apache. I have a css page that I reference in my base template with a relative path, like so:

<link rel="stylesheet" href="/common/css/base.css" type="text/css" />

So, if you append that to the DocumentRoot, you can find that in my file system.

One tricky thing to note here. The admin page looks in a specific location for its css content. In my case, I moved it to "/usr/local/www/django/prj_1/static/admin/media/css". So, if you combine my DocumentRoot, which is "/usr/local/www/django/prj_1/static/", with the "ADMIN_MEDIA_PREFIX" setting in the settings.py file, you get "/usr/local/www/django/prj_1/static/admin/media/". This will allow the builtin admin app to find the css files.

views

First, the PythonPath got us to the urls.py, the urls.py maps to views. This is one of the significant new concepts I'm still learning. With LAMP or plain html, you type a url in a browser, then Apache resolves it to a physical disk location. Now, when you type in a url, if it's in the PythonPath, Apache lets Python do what it wants to with it. In the case of Django, it hands it over to urls.py, then urls.py sends it to the appropriate view. The view then does any programming on it that it needs to do, then displays a template.

templates

Templates are named with an html extension. If you come from a LAMP background like me, you can get a little confused thinking your DocumentRoot will resolve these for you. But, Python handles this. It's easy enough to put use the TEMPLATE_DIRS directive in the settings.py file. Then, you will likely be referencing your templates inside your views. For example, my TEMPLATE_DIRS is set to '/usr/local/www/django/prj_1/templates'. In my views, when I want to reference a template, I imagine it being appended to that path. So, my index.html in "/usr/local/www/django/prj_1/templates/app2/index.html" is referenced by combining my TEMPLATE_DIRS and what I have coded in my view.py.

apps

Apps are pretty straight forward, they are resolved by the settings.py. You probably new that from going through the tutorial.

2 comments: