Surgo

lazy programmer. (simple is better than complex !)

Feb 21, 2010

パーフェクトな Django の設定ファイル

"DAMON BLOGONS" の、 "The Perfect Django Settings File" という記事で紹介されていた Django の設定 (settings.py) が面白かったので、私が利用しているものと併せて紹介したいと思います。

環境による DEBUG の切り分け

開発環境では "DEBUG = True" と書くと幸せになれます。Django のデバッガーは強力です。ただし、本番環境にそのままデプロイしてしまうと・・・。デプロイを楽にするためにも、失敗を防ぐためにも自動的に切り分けるのが望ましいですよね。Damon 氏は以下のようなコードで切り分けているようです。

# Set DEBUG = True if on the production server
if socket.gethostname() == 'your.domain.com':
    DEBUG = False
else:
    DEBUG = True

開発環境 localhost (127.0.0.1) と運用環境 your.domain.com のホスト名の違いを利用して切り分けています。

データベース設定

データベースの設定も開発環境と本番環境では違います。Damon 氏は 2 つのファイルを使い切り分ける方法を紹介しています。この方法は私もよく使います。これは pinax でも利用されている方法です。1 つは本番環境の設定をそのまま記述したファイル (settings.py) で、もう 1 つが開発環境の設定を記述したファイル (local_settings.py) です。settings.py の最後に、以下のコードを書いておき、 local_settings.py は本番環境にデプロイしないことで設定を切り分けています。

try:
    from local_settings import *
except ImportError:
    pass

local_settings.py で settings.py の内容を上書きします。私はデータベースの設定だけでなく、上述した DEBUG 設定なんかの上書きに使っています。local_settings.py はバージョン管理ソフトの除外リスト(mercurial なら .hgignore、subversion なら global-ignores など) に追加しておくと便利です。※ このページの後述に DEBUG スイッチなるものが記述されていますが、私の場合はせっかくなので、すべて local_settings.py に記述しちゃいます。

メディアルート

フルパスで記述してしまうと再利用性が損なわれてしまいます。以下のコードのように、実行時に動的にパスを取得することにより、解決できます。これも Django の長所、"設定ファイルが python ファイル" を活用したいい例だと思います。

PROJECT_PATH = os.path.realpath(os.path.dirname(__file__))
MEDIA_ROOT = os.path.join(PROJECT_PATH, 'media')

PROJECT_PATH で settings.py (__file__) の保存されているディレクトリまでのフルパスを取得し、そのディレクトリ内の media ディレクトリを MEDIA_ROOT としています。

以上、抜粋です。 Damon の settings.py は gist に保存されています。その他のチップスは Damon 氏のページを参照してみてください。

MEDIA の URL

せっかくなので、私が利用しているデフォルトの urls.py のチップスを 1 つ。静的ファイルがボトルネックになってしまってはいけないので、本番環境は静的ファイルを別サーバに保存することが多いでしょう。よって urls.py も本番環境と開発環境では変わることがありますよね。私は、local_settings.py と同様に local_urls.py を作っています。OAuth とかテスト用の Web サービスのテストなどにも便利ですよ。

# urls.py
urlpatterns = patterns(
   # 本番環境の URL たち
)

try:
    from local_urls import urlpatterns as test_patterns
    urlpatterns += test_patterns
except ImportError:
    pass
# local_urls.py
import re

from django.conf import settings
from django.conf.urls.defaults import patterns, url

base_url = re.escape(settings.MEDIA_URL[1:])
urlpatterns += patterns('django.views.static',
        url(r'^%s(?P<path>.*)$' % base_url, 'serve',
            {'document_root': settings.MEDIA_ROOT}),
    )

便利なのでぜひお試しください :-) それと、ぜひ皆さんが使っていらっしゃる テクニック も教えてほしいです。

blog comments powered by Disqus

about

friends

archives

Kosei Kitahara.

surgo.jp at gmail.com

hosted at blogger.