プロジェクトファイルとWSGIHandler

初期ファイル

django-admin.py startproj foo_bar 

で出来る4つの*.py

  • __init__.py
  • manage.py
  • settings.py
  • urls.py

についてのメモ。

__init__.py

ディレクトリをモジュールインポート可能ディレクトリ(パッケージインポート出来る)として認識させるファイル。

中にコードを書くとパッケージインポート時の初期化処理に使われる。

http://atkonn.blogspot.com/2008/02/python-python38.htmlとかhttp://blog.livedoor.jp/th10/archives/1945085.htmlなどを参照。

manage.py

setting.pyの設定を付加したdjango-admin.pyと考えておきたい。

setting.py

いわゆるコンテナ型(リスト、タプル、辞書)オブジェクトと非コンテナ型オブジェクト(変数)混在の初期設定変数値。

urls.py

URL dispatcher (ルーティング)設定。

http://d.hatena.ne.jp/monajiro/20100329 の記事がわかりやすい(ただしDjango ver. < 1.3時の設定)。

nginx+uwsgiからの起動:wsgi:WSGIHandler()の動作

実際のHTTPリクエストがあったとして、どのようにPython/Djangoが動くかということを理解しておく。

nginx+uwsgiならuwsgiのmodule設定された

django.core.handlers.wsgi:WSGIHandler()

のインスタンスからスタートする。

なおApacheの場合、mod_phytonを使うとhttpd.confのPythonHandlerディレクティブで

PythonHandler django.core.handlers.modpython

で動作させるようである(*1)。もちろんApacheでもmod_wsgiを使うとnginx+uwsgiと一緒のモジュールが使われる(*2)。

さてPythonのお勉強をかねてdjango.core.handlers.wsgiのソース

/usr/local/lib/python2.7/site-packages/django/core/handlers/wsgi.py

を眺める。

wsgi.py

grep "^class" /usr/local/lib/python2.7/site-packages/django/core/handlers/wsgi.py

class LimitedStream(object):

class WSGIRequest(http.HttpRequest):

class WSGIHandler(base.BaseHandler):

クラスは3つ。これ以外にHTTPのStatus Code(rfc2616)の辞書リスト定義

WSGIHandlerクラス

class WSGIHandler(base.BaseHandler)は__call__メソッドのみを持つクラスである。

def __call__(self, environ, start_response):

django.core.handlers.wsgi:WSGIHandler()という関数呼び出しなので__call__が実行される。__call__についてはライブラリレファランス「データモデルの特殊メソッド名」の __call__ 参照。

以下、その中身を見る。なお、settingsにてmiddleware(MIDDLEWARE_CLASSES)が定義されていた場合は、middlewareが処理されるが、ここでは省略し次項で記述)。

WSGIHandler内からWSGIRequest呼び出し。WSGIRequestからLimitedStream呼び出し。WSGIHandlerによるリクエスト処理。

  1. 変数request_classにWSGIRequestインスタンスを入れる
  2. WSGIRequestはhttp.HttpRequestクラスを継承しており__init__メソッドが存在。
  3. request = self.request_class(environ)で、上記 __init__によってインスタンス変数がセットされる(*3)。
  4. WSGIRequestの__init__の最後ではLimitedStreamクラスが呼び出される。LimitedStreamは

LimitedStreamは

LimitedStream wraps another stream in order to not allow reading from it past specified amount of bytes.

である。

WSGIHandlerは上の処理requestをうけて

  1. 変数responseにself.get_response(request)を入れる
  2. なおget_responseメソッドは、WSGIHandlerの親クラス base.BaseHandler内で定義されている。

get_response

  1. settings.ROOT_URLCONFのURL dispachter(ルーター)定義(のモジュール)のメソッドをcallbackで処理する。
  2. 処理出来ない場合、404,403を返す。

以上(*4)。

middleware=フック

settingsに定義されているmiddlewareが存在する場合、上の処理中にその都度呼び出される。ようするに「フック」である。settingsに標準設定されているものは下記。

MIDDLEWARE_CLASSES = (
 'django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
)

Djangoのビュー(コントローラ)(*5)との関係は下記のDjangoの概念図を参照。

no title


https://docs.djangoproject.com/en/dev/topics/http/middleware/






*1: http://djangoproject.jp/doc/ja/1.0/howto/deployment/modpython.html

*2: http://serverfault.com/questions/119951/django-wsgi-py-whats-the-difference

*3: http://www.geocities.jp/m_hiroi/light/python05.html

*4: このレスポンス前後に「シグナル」の処理がされているhttp://djangoproject.jp/doc/ja/1.0/topics/signals.html

*5: Djangoの場合MVCと言わず、Model,Template,Viewという。View=Controller,Controller=Viewという呼称には、まだ、慣れない。

this file --> last modified:2012-03-31 13:57:56