Django アプリケーション

Django プロジェクトは大体の場合、 INSTALLED_APPS に宣言された数々のアプリケーションから成ります。Django アプリケーションは、小さくあること、モジュール (組立部品) であることにフォーカスした、 Unix の哲学 “一つのことを、うまくやれ (Do one thing and do it well.) ” [1] に従うべきであり、Django の “ルースカップリング” 設計哲学 [2] を反映すべきです。

最初の DjangoCon での James Bennett による 再利用可能なアプリトーク は、 Django での良いアプリケーションの構築を主題にした、とても良く出来た入門です。

[1]http://en.wikipedia.org/wiki/Unix_philosophy#McIlroy:_A_Quarter_Century_of_Unix
[2]https://docs.djangoproject.com/en/dev/misc/design-philosophies/#loose-coupling

コード構成

Django アプリケーションにただ 1 つ必要なものは models.py ファイルで提供されるものです。ただ、このプラクティスでは、 Django アプリケーションはいくつもの種類が違うファイルから成り立ちます。あなたがアプリケーションをビルドする場合、共通のファイル命名規則に従ってください。 manage.py startapp <foo> を実行することで Django が提供するフレームワークで開発を始め、必要に応じて増築してください。

  • __init__.py
  • admin.py
  • context_processors.py
  • feeds.py
  • forms.py
  • managers.py
  • middleware.py
  • models.py
  • receivers.py
  • signals.py
  • templates/app_name/
  • templatetags/
    • __init__.py
    • app_name.py
  • tests.py または tests/
  • urls.py
  • views.py

これらのファイルの中で動かすものは、一つ一つが一見して、それが何なのかすぐに分かるものであるべきです. さぁ、始めましょう。(Let’s dive into some of the meatier ones though.)

モデル

スタイル

モデルのコードは Django の 決定済み規約 に従いましょう。

モデルを太らせましょう

MVC-スタイルプログラミングでの共通パターンは、太ったモデルと痩せたコントローラーを構築するものです。Django ではこれを次のように読み替えます。自身に関係する沢山の小さなメソッドを持ったモデルの構築、モデルに付随するメソッドを使い、自身では可能な限りミニマルなロジックを保つビューです。このアプローチには多くの利点があります。

  1. DRY: 複数のビューに同じロジックを繰り返し書くより、モデル内に一度だけ定義。
  2. テスト可能: モデルのロジックを小さなメソッドに切り出していくことで、あなたのコードがユニットテストしやすくなる。
  3. 読みやすさ: あなたのメソッドに分かりやすい名前を付けることで、ひどいロジックを、読みやすくて分かりやすいものにまとめられる。

Django における太ったモデルの良い例としては、 |django.contrib.auth.models.User の内容|_ を参照してください。

マネージャー

モデルに似て、共通のロジックをマネージャーの中にまとめるのも良いやり方です。より具体的に言うと、多分、あなたは、クエリセットとして使えるようなチェーンメソッドが欲しくなるでしょう。これは私がいつも忘れるボイラープレートを含みます。ここに (ほぼ) コピー・アンド・ペーストした例を記載します

import datetime
from django.db import models
from django.db.models.query import QuerySet

class PostQuerySet(QuerySet):
    def live(self):
        """公開の準備が出来てない投稿をフィルタリングする"""
        now = datetime.datetime.now()
        return self.filter(date_published__lte=now, status="published")

class PostManager(models.Manager):
    def get_query_set(self):
        return PostQuerySet(self.model)
    def __getattr__(self, attr, *args):
        # 詳しくは https://code.djangoproject.com/ticket/15062 を参照
        if attr.startswith("_"):
            raise AttributeError
        return getattr(self.get_query_set(), attr, *args)

class Post(models.Model):
    # フィールド定義
    objects = PostManager()

このコードにより、 Post.objects.live() とクエリセットを使ってメソッドチェーン化した Post.objects.filter(category="tech").live() の両方のマネージャーから、新たなメソッド live を直接コールすることができます。コードを書く際には an open bug を見ると手間を減らせると思います。