views:

48

answers:

2

Summary:

Say I have a project in Django called "devsite" which will be deployed first to a staging project (also called "devsite") and finally to the live codebase (where the project is called "livesite"). During live deployments, I'd have to make manual changes to urls.py in order to import views from the right project. Which means urls.py in "devsite" would use something like:

from devsite import views

And urls.py for "livesite" would be changed to:

from livesite import views

My Solution:

The following seems to work (with limited testing so far). What I've done is create a variable in settings.py to get the project name from the directory, like so:

settings.py

# /settings.py
import os.path
PROJECT_NAME = os.path.basename(os.path.dirname(__file__))

And then use this to import the correct views in urls.py:

urls.py

# /urls.py
from django.conf import settings
website = __import__('%s' % settings.PROJECT_NAME, fromlist=['views'])
...
urlpatterns = patterns('',
    (r'^monty/$', website.views.monty),
)

My Question:

What I'd like to know is:

  1. Is this a good way of doing what I want to do, or is there a better way to code this?
  2. Or do I need to rethink my whole deployment workflow?

Thanks in advance.

A: 

I would question why you have different projects for your live and dev sites. Why not keep all differences down to settings/configuration (as you do with PROJECT_NAME, for example) but keep your projects common? It seems you only increase any chances for error between dev and live the more you make each site diffferent.

Other than that, I think what you're doing is more or less fine. The other pattern I've seen is something like:

try:
    from livesite import views
except ImportError:
    from devsite import views
ars
On my local machine, the source only exists as the devsite project. It's only on the remote host where I first deploy that devsite code into the staging project, and then deploy it to the livesite project. My logic at the time was that I could serve both of these from the same Django install. But I see flaws in that setup now; for example, when it comes time to upgrade Django.I had seen the "try except" pattern you mentioned, but I didn't want the solution to be coupled to the project name, in case I ever changed the name.I'll go with a single project name. Thanks for making me rethink it.
stevelove
+1  A: 

Have a look at zc.buildout and djangorecipe - which, as Jacob Kaplan-Moss puts it,

...is an exceedingly civilized way to develop an app

http://jacobian.org/writing/django-apps-with-buildout/

Apart from general 'civilizedness", djangorecipe allows you to have more than one settings file, which can import from each other. Then you can specify which settings file to use in a particular installation.

development.py

from settings import *
DEBUG = True

live.py

from settings import *
DEBUG = False

... and that's only the tip of the iceberg

Sergey
This does look great. I'll keep it in mind for future projects, though right now it's probably overkill for the simple project I'm working on.
stevelove