Article

Djangoによる家計簿アプリケーション

※ 商品リンクから購入されると少額の報酬が発生することがあります。

ずっと作ろう作ろうと思っていた家計簿を、せっかくだからDjangoで作ってみた。

作ろうと思うたびに、モデリングとフレームワークの選定でお腹いっぱいになってしまっていたので、Djangoの チュートリアル2 まででできる内容を作ってみた(データベースにデータさえ入れれば、あとはどうにでもなるし)。

  • とりあえずの要件

    現状は、自分が嫁のレシートを入力するだけなので、管理画面までの作成。

    集計は直にSQLでするかもしれない(どんな集計をするのかは、ある程度データを投入してみてから考える)。

    難しくしない

  • 主な考え方

    出費をレシートとしてとらえる

    レシートの内訳に、カテゴリをつける

    カテゴリはグループに属する(グループは、衣・食・住・社会保険・税等のレベルで作ろうと思う)

    レシートには店をつける

で、書いたコードは次のようになった。

from django.core import meta

# Create your models here.
class Store(meta.Model):
  fields = (
    meta.CharField('name', 'Store Name', maxlength=50, core=True),
  )
  admin = meta.Admin()

  def __repr__(self):
    return self.name

class CategoryGroup(meta.Model):
  fields = (
    meta.CharField('group_name', 'Category Group name', maxlength=100, core=True),
  )
  admin = meta.Admin()

  def __repr__(self):
    return self.group_name

class Category(meta.Model):
  fields = (
    meta.CharField('name', 'Category Name', maxlength=100, core=True),
    meta.ForeignKey(CategoryGroup),
  )
  admin = meta.Admin()

  def __repr__(self):
    return self.name

class Receipt(meta.Model):
  fields = (
    meta.DateField('buy_date', 'buying date', core=True),
    meta.TextField('memo', 'memo'),
    meta.ForeignKey(Store),
  )
  admin = meta.Admin(
    list_display = ('buy_date', 'store', 'totalPrice'),
  )

  def __repr__(self):
    return self.buy_date.strftime('%Y-%m-%d') + ':' + self.get_store().name

  def store(self):
    return self.get_store().name

  def totalPrice(self):
    totalPrice = 0
    tmpList = self.get_item_list()
    for i in range(len(tmpList)):
      totalPrice += tmpList[i].totalPrice()
    return totalPrice

class Item(meta.Model):
  fields = (
    meta.CharField('name', 'Item Name', maxlength=50, core=True),
    meta.IntegerField('price', 'Item Price', core=True),
    meta.IntegerField('amount', 'num', core=True),
    meta.CharField('memo', 'Item memo', maxlength=500),
    meta.ForeignKey(Receipt, edit_inline=True, num_in_admin=5, edit_inline_type=meta.TABULAR),
    meta.ForeignKey(Category),
  )

  def __repr__(self):
    return self.name

  def totalPrice(self):
    return self.price * self.amount
  totalPrice.short_description = "Sub Total Price"

上記のコード以外に書いたりしたりしたこと

  • PostgreSQLに家計簿用のユーザとデータベース(UNICODE)を作成

  • Djangoの管理コマンドを発行(イニシャライズ、家計簿プロジェクト開始、家計簿プロジェクトインストール、家計簿スーパユーザ作成)

  • Djangoの設定(データベースの種類・データベースユーザ・データベース名の記述のみ)

できあがった物

  • レシートの一覧画面(ログイン後、レシート一覧の表示を選択すると表示される)

  • レシートの追加、編集画面(レシート一覧の行をクリックするか、追加をクリックすると表示される)

関連を持たせたモデルについては、いくつかの手法で同時に追加できる。

上記のレシートと明細については、レシート入力時に同時に明細を追加できる。

明細とカテゴリ、カテゴリとカテゴリグループについては、子供の追加時に必要な親が書けている場合、+をクリックすると別ウィンドウが表示されて親の入力ができ、即座に子供の入力に使用できるようになる(現状では+を押した子供の入力値リストにのみ反映される。一度空でサブミットして、バリデーションでこけさせる等の運用が必要。Djangoはリリースされていないステータスのものだからとりあえずあきらめる)。

Djangoの感想

フロントを作っていないので、まだ微妙な感想

  • 入力文字列に'があっても日本語であっても全く問題ない。

  • メニュー表示等のi18nは現在Djangoprojectの方で検討されている模様。

    ただし、日本人の姿を見かけないので、このまま放置すると日本語が扱われるかどうかは怪しい。

  • 現状では、モデルからデータベースの作成というトップダウン方式にしか対応していない。

  • ついデータベースをドロップしてしまうと、アプリケーションレイヤーでないテーブルが消えてしまってつらい(initしなおし)。

  • とりあえず、いい感じ(まだまだRailsが勝っているらしいが、Railsを使ってみていないので何ともいえない。

  • Ajaxコンポーネントもsvnには存在する(ドキュメントか何かもネットで見かけた)

  • チュートリアル3をちら見した感じだと、テンプレートはXML系ではない

  • 簡単な管理画面のみ必要なものについては、かなり速く作れる(今回のはなれれば5分くらいだろう)

Prev Entry

Next Entry