ホーム >

Django

開発サーバーを他のパソコンから見れるようにする

Djangoの開発サーバーはデフォルトではlocalhostからしかアクセス出来ない。 他のパソコンから見れるようにするには、IPアドレスとポート番号を指定して 開発サーバーを起動すればよい。

python manage.py runserver 192.168.0.1:8000

mod_pythonでDjangoを動かす

apacheの設定例。 adminを利用する場合、adminで使用するcssなどのファイルを静的配信する必要がある。

<Location />
   SetHandler python-program
   PythonHandler django.core.handlers.modpython
   SetEnv DJANGO_SETTINGS_MODULE settings
   PythonDebug Off
   PythonPath "['/path/to/django_project'] + sys.path"
</Location>

Alias /media /opt/local/lib/python2.6/site-packages/django/contrib/admin/media
<Location /media>
   SetHandler None
</Location>

mod_wsgiでDjangoを動かす

mod_wsgiでDjangoを動かす場合、次のようなスクリプトを作成し、 apacheの設定ファイルでWSGIScriptAliasディレクティブを使って そのファイルを指定する。

import os
import sys

os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

apacheの設定例

WSGIScriptAlias / /path/to/wsgi_file

Alias /media /opt/local/lib/python2.6/site-packages/django/contrib/admin/media
<Location /media>
   SetHandler None
</Location>

nginx + gunicornでDjangoを動かす

gunicornをつかってDjangoサーバを立ち上げる方法には、 Djangoのmanage.pyを使用する方法と、gunicorn_djangoコマンドを使用する方法がある。

manage.pyを使う場合は、まずsettingsモジュールのINSTALLED_APPSに'gunicorn'を追加する。

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.admin',
    'app1',
    'gunicorn',
)

こうすることで、manage.pyで新たにrun_gunicornコマンドが使用可能となる。 gunicornプロセスを起動するには、次のようにコマンドを実行する。

./manage.py run_gunicorn [options]

gunicorn_djangoを使用する方法の場合、次のようにコマンドを実行する。

gunicorn_django [options] /path/to/settings.py

manage.pyを使う方法だと、settings.pyが標準以外の場所だとうまくいかない?ので、 gunicorn_djangoを使う方法をおすすめする。

オプションの与え方に関しては、コマンドライン引数で一つ一つオプションを指定してもよいが、 設定ファイルを作って--configオプションで指定する方法がスマート。

設定ファイルの例(設定ファイルの文法はpythonの文法そのもの)

bind = 'unix:/tmp/gunicorn_app1.sock'

backlog = 2048
workers = 1
worker_class = 'sync'
worker_connections = 1000
max_requests = 0
timeout = 30
keepalive = 2

debug = False
spew  = False

preload_app = True
daemon = True
pidfile = '/var/run/gunicorn/app1.pid' # 起動前に/var/run/gunicornを作成する
user  = 'app1_app'
group = 'nginx'
umask = 0002

logfile = '/var/log/gunicorn/app1.log' # 起動前に/var/log/gunicornを作成する
loglevel = 'info'
logconfig = None

proc_name = 'gunicorn_app1'

UNIXドメインソケットを使ってnginxと通信を行う場合、 nginxプロセスがそのソケットにアクセスする権限を持つ必要がある。 そのため、ここではgunicornプロセスのgidをnginx(ソケットのownerはapp1:nginxとなる)とし、umaskでグループの読み書きを許可している。 (gunicornプロセスのユーザをnginxプロセスと同一にすればumask=0022でもOK)

nginx側の設定では、upstreamディレクティブで上記gunicorn設定ファイルで指定したソケットのパスをサーバアドレスに指定する。 また、Djangoのadminを使用する場合、adminで使用する静的ファイルをnginxで配信するように設定する。

nginxの設定例

# /etc/nginx/nginx.conf
user  nginx;
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    sendfile           on;
    tcp_nopush         on;
    keepalive_timeout  5;
    gzip               on;

    include app1.conf;
}
# /etc/nginx/app1.conf

upstream app1-backend {
    server unix:/tmp/gunicorn_app1.sock fail_timeout=0;
}

server {
    listen       80;
    server_name  app1.mydomain.com;

    access_log  /var/log/nginx/app1.mydomain.com-access.log main;
    error_log   /var/log/nginx/app1.mydomain.com-error.log  info;

    location ~ /media/(.*)$ {
        alias /opt/local/lib/python2.7/site-packages/django/contrib/admin/media/$1;
        break;
    }

    location / {
        proxy_pass http://app1-backend;
        break;
    }
}

reStructuredText(Docutils)を使うためのTips

Docutilsの設定を変更する

Docutilsの設定を変更する場合、プロジェクトのsettings.pyの中で、 RESTRUCTUREDTEXT_FILTER_SETTINGSというの名前の辞書を作成する。 例えば、見出しで使うタグをh1やh2ではなくh3やh4にする場合、 settings.py中に以下の行を追加する。

RESTRUCTUREDTEXT_FILTER_SETTINGS = dict(initial_header_level=3)

ディレクティブを定義する

reStructuredTextのディレクティブを自分で定義することができる。 ディレクティブを定義する手順は、

  1. docutils.parsers.rst.Directiveを継承したクラスでrunメソッドを定義する。
  2. runメソッドでdocutils.nodes.Nodeのサブクラスのインスタンスのリストを返す。
  3. 作成したディレクティブのクラスをdocutils.parsers.rst.directives.register_directiveで登録する。

ちなみに、このサイトはDjangoでreStructuredTextを使って書かれている。 プログラムのソースコードを記述したHTMLに自動的にクラスを追加するために、 以下のような拡張を行っている。

from docutils import nodes
from docutils.parsers.rst import directives
from docutils.parsers.rst import Directive

class ProgramLiteral(Directive):
  required_arguments = 0
  optional_arguments = 0
  has_content = True
  additional_classes = []

  def run(self):
    row_text = "\n".join(self.content)
    literal_block = nodes.literal_block(row_text, row_text)
    literal_block['classes'] += self.additional_classes
    return [literal_block]

class PythonLiteral(ProgramLiteral):
  additional_classes = ['python', 'sourcecode', 'prettyprint']

class RubyLiteral(ProgramLiteral):
  additional_classes = ['ruby', 'sourcecode', 'prettyprint']

class BashLiteral(ProgramLiteral):
  additional_classes = ['bash', 'sourcecode', 'prettyprint']

class HTMLLiteral(ProgramLiteral):
  additional_classes = ['html', 'sourcecode', 'prettyprint']

class XMLLiteral(ProgramLiteral):
  additional_classes = ['xml', 'sourcecode', 'prettyprint']

class JavascriptLiteral(ProgramLiteral):
  additional_classes = ['javascript', 'sourcecode', 'prettyprint']

class LispLiteral(ProgramLiteral):
  additional_classes = ['lisp', 'sourcecode', 'prettyprint']

directives.register_directive("python", PythonLiteral)
directives.register_directive("ruby", RubyLiteral)
directives.register_directive("bash", BashLiteral)
directives.register_directive("html", HTMLLiteral)
directives.register_directive("xml", XMLLiteral)
directives.register_directive("javascript", JavascriptLiteral)
directives.register_directive("lisp", LispLiteral)

参考URL

SSLを使う

  1. djangosnippets.org で紹介されているスニペットを sslmiddleware.pyとして保存する。

  2. プロジェクトのsettings.pyのMIDDLEWARE_CLASSESにsslmiddleware.SSLRedirectを追加する。

  3. urls.py中でのSSLを使いたいURLのオプションに{'SSL' : True}を渡す。 例えば、/admin以下でSSLを使う場合、プロジェクトのurls.pyを以下のようにする。

    urlpatterns = patterns('',
        (r'^admin/', include(admin.site.urls), {'SSL' : True}),
    )
    

静的ファイルを配信する

Djangoで静的ファイルを配信するには、 view関数django.views.static.serveを使う。

プロジェクトのurls.pyが置いてあるディレクトリの下にstaticという名前のディレクトリがあり、 その中のファイルを /static 以下に配置したい場合以下のように記述する。

(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root' : /absolute_path/to/static/})

通常、この方法は開発サーバーのみで行う。 本番用の環境では、Apache等のウェブサーバー側の設定で静的ファイルの配信を行うようにする。

if settings.DEBUG:
  import os
  base = os.path.abspath( os.path.dirname(__file__) )
  document_root = os.path.join(base, 'static')
  urlpatterns += patterns('',
                          (r'^static/(?P<path>.*)$',
                           'django.views.static.serve',
                           {'document_root' : document_root}),
                          )