Djangoで家計簿サービスを開発してリリースするまで 【個人開発】

:::note info

DAIFUKUは2022年8月1日に[SUMUMA](https://sumuma.com/lp/general/)へと生まれ変わりました。
:::

2019年1月に、ひっそりとDAIFUKUというサービスをリリースしました。
個人で開発した家計簿サービスで、現在は誰でも無料で利用できます。

![daifuku.png](https://qiita-image-store.s3.amazonaws.com/0/243199/8ea49591-afb8-1c27-1851-e83222e9b98e.png)

上の画像は知り合いの漫画家に描いてもらったDAIFUKUのキャラクターです。

> DAIFUKU
https://daihuku.xyz

# 目次
1. [私について](#私について)
2. [Djangoを選んだ理由](#djangoを選んだ理由)
3. [なぜ家計簿か](#なぜ家計簿か)
4. [DAIFUKUの開発について](#daifukuの開発について)
  1. [CSSフレームワーク](#cssフレームワーク)
  2. [本番環境](#本番環境)
  3. [機能とデザイン](#機能とデザイン)
  4. [セキュリティ](#セキュリティ)
5. [今後のDAIFUKU](#今後のdaifuku)

# 私について
新卒1年目のWebエンジニアです。大学時代からWebエンジニアをやっているため、経験年数で言うと2年近くあります。
仕事ではPHP、Ruby、JavaScript、SQLなどを使っており、CakePHP、Rails、WordPressなどのフレームワークやCMSを使ったWeb開発をしています。
今回開発したDAIFUKUはDjangoで実装しているのですが、仕事では全く使っていません。Pythonも仕事では全く使っていませんが、一番できる言語はPythonで一番できるフレームワークはDjangoです。
Django歴をざっとお話すると、始めたのが2018年5月なので2019年2月現時点で9ヶ月ほどです。最初は[Django Girls チュートリアル](https://tutorial.djangogirls.org/ja/)をやって、次にDjangoの公式ドキュメントにあるチュートリアルをやりました。

# Djangoを選んだ理由
個人的にPythonをよく使っており、もっとPythonを極めたいと思ったのがきっかけです。
また、学習コストが他のフレームワークに比べて低いため、作りたいものをさくっと作るのには向いているからです。個人開発にもなるとあまり時間をかけてはいられないので、Djangoを選ぶ価値は十分にあると考えました。

それと、Djangoはこれからくるんじゃないかなと思ったのもきっかけです。Djangoで開発された日本のサービスはあまり見かけませんが、海外だと、Django製の有名サービスはいくつかあります。例えば[Instagram](https://www.instagram.com)、[Pinterest](https://in.pinterest.com/)、[Bitbucket](https://bitbucket.org)、[NASA](https://www.nasa.gov)、[Mozilla Support](https://support.mozilla.org)など日本でもよく見かけるサービスがDjangoで作られたりしています。
最近、海外の人から聞いた話ですが、DjangoとRailsの英語の情報量を見比べてみるとDjangoの方が多くRailsは少ないそうです。

日本の中だけだとRailsやLaravelが優位ですが、Djangoも徐々に力をつけているので、2019年4月リリースのDjango2.2（LTS）を境にもっと普及するのではないかと考えています。
よくDjangoは情報量が少ないというのを言っている人がいるのですが、現在だとそれなりに日本語の情報も出てくるのでそこまで不自由することはないというのが個人の見解です。

## ディレクトリ/ファイル構成がいい
DjangoはMTV(MVCみたいなもの)が機能ごとに独立したような構成になっており、非常に俯瞰がしやすく管理がしやすいです。

## ORMがいい
個人的には、DjangoのORMは読みやすく理解しやすいので良いと思っています。
ざっとこんな感じですというのを紹介します。

### 条件検索

不等号などの記号を使わないところがいいですね。

```py:
Users.objects.filter(birth__range=['20180101', '20181231'])
Users.objects.filter(age__gte=18)
```

### 1対1 / N対1

```py:
Books.objects.select_related('author')
```

### 1対N / N対N

```
author = Authors.objects.(id=1)
author.books_set.all()
```

### 関連先テーブルで条件をさらにかける

```py:
books = Authors.objects.filter(
            id__in=[1,2,3,4]
        ).prefetch_related(
            Prefetch(
                'category_set',
                    queryset=Categories.objects.filter(genre__in=['SF','ミステリー','恋愛','推理']),
                    to_attr='categories'
            )
        )
```

> この記事がDjangoのDB操作を一通りまとめてくれているので重宝しています
https://qiita.com/okoppe8/items/66a8747cf179a538355b

# なぜ家計簿か
DAIFUKUは家計簿を付けるためのサービスなのですが、家計簿にした理由はいくつかあります。
1つは自分が理想とする家計簿がなかったからです。世の中には多くの家計簿アプリがありますが、UI/UXに関して使いにくいものやデザインが今時じゃないものなどが多い印象です。また、自分の収支状況を簡単に分析し次に活かせられるようなアプリを探していたのですが、そういうアプリに出会えなかったので自分で作ってみることにしました。
私自身家計簿のプロでもないので試行錯誤しつつ開発をしていくつもりです。

もう1つ理由があるのですが、個人的にデータサイエンティストという職業に興味があり、集めたデータを使って分析し、サービスに活かすというのをやってみたかったためです。
※集めたデータを変なようにはしないのでご安心ください。

# DAIFUKUの開発について
設計をやり始めたのが2018年の8月半ぐらいなのでリリースまでに5ヶ月ほどかかりました。最初の設計は、紙にER図や画面の構成をかいたりして大枠を決め、zohoの表計算シートにテーブル定義を書き込んでシステムの土台を組み立てていきました。また、使用するCSSフレームワークや本番で使用するミドルウェアなどもこの段階で調査して決定しました。ここについては後ほど詳しく説明します。
テスト環境はHerokuサーバーを採用しました。Herokuだと制限はあるものの無料で利用でき、Djangoアプリケーションの立ち上げもドキュメントが揃っているので比較的容易に導入ができました。本来だと本番環境と同じサーバーで同じ環境でステージングやテスト環境を構築するのが望ましいのでしょうが、ソースコードをアップすると自動デプロイしてくれるのとお財布が厳しいのでHeroku無料枠を使っています。そのうち、本番と同じサーバーを追加でレンタルしてステージングとテスト環境を作りたいです。

## CSSフレームワーク
CSSフレームワークは[Semantic UI](https://semantic-ui.com/)を採用しています。Semantic UIは日本語のドキュメントが充実していて、BootStrapよりもコンポーネント数、機能、デザイン、書きやすさは断然優れています。さらにTwitter風、Amazon風、GitHub風のテーマがあるのも特徴です。
`Semantic` というのは「意味の」といった意味ですが、クラス指定に意味を持たせてHTMLを記述することができます。なにを言ってるかわからない方は、実際にSemaintic UIを使ってみてください。BootStrapを使っている人が不思議に思えるぐらいSemantic UIは優れていると思えるはずです。

> こちらの記事にSemantic UIのいいところがまとまっています
http://web-and.me/semantic-ui/

## 本番環境
サーバーはConoHaを使っており、VPSとDBをレンタルしています。ConoHaは管理画面がきれいで動作も速く、環境の構築も一瞬でできてしまうのでかなりおすすめです。使用した時間分での課金というのも良い点です。あとこのはちゃんが良いですね。とても良いです。

OSはUbuntu、ミドルウェアはNginx、MariaDBで、WebアプリケーションとWebアプリケーションサーバーのインターフェースにはuWSGIを採用しています。
それぞれ採用した理由を述べるとUbuntuは単に自分がよく使っているためです。蛇足ですが、Ubuntuは南アフリカの言葉で「他社への思いやり」という意味だそうで、カノニカル社の支援を受けながら開発されているそうです。まさに、「他社への思いやり」を見事に達成しているディストリビューションです。
Nginxについては設定が直感的でわかりやすいことと、CPUの処理を多く必要としないことを想定しているためです。
MariaDBは、これといって大きな理由はありませんがMySQLに使い慣れていることと、MySQLよりもセキュリティ面、処理性能などのパフォーマンスに優れているためです。実際にGoogleなどもMariaDBを採用していたり、MySQLと違って全ての機能が無償で利用できるので利用価値は十分にあります。また、オープンソースでもあるので今後のスタンダードなっていくのではないかと思います。
uWSGIに関してはとくにこだわりはなく、「django nginx」とかで調べるとuWSGIを使っている記事が多く出てきたためです。

> このuWSGIのチュートリアル和訳には大変助かりました。
https://qiita.com/Ningensei848/items/e91fbeef5f03685a7a0b

## 機能とデザイン

![daifuku_kakeibo_top2019-02-20.png](https://qiita-image-store.s3.amazonaws.com/0/243199/42806cad-04bb-9eb1-9f40-2bb4606b0c33.png)


デザインについては、なるべくストレスフリーな操作性を意識して開発しました。例えば、ログイン後の画面で遷移ぜずに支出、収入、カテゴリの登録をできるようしたほか、直近30日の支出履歴を表示しておくことで収支をどこまで追加したか、確認しつつ登録をできるようにしました。また、日毎の支出額をグラフ化し、ぱっと見て支出状況を把握できることもポイントです。
外観については、フラットデザインを採用することで視覚情報を最低限まで減らし、シンプルで統一感を出すようにしました。
現状の機能は、収支を登録できることはもちろん、収支履歴(カテゴリや期間の絞り込み検索可)、CSVエクスポート/インポート、収支分析、収支計画機能などを付けています。
収支計画機能については、ただ登録するだけでは家計簿として不十分で意味がないと思ったのでこのような機能を付けました。
機能としてはまだまだ不十分ですが、これからもっと充実させていこうと考えています。
ちなみに、お問い合わせフォームもあるので追加して欲しい機能やバグなどがあればご一報頂けると幸いです。

### 収支計画画面
![budget_plan from 2019-02-20.png](https://qiita-image-store.s3.amazonaws.com/0/243199/02ba3010-41fa-2b32-79ed-ee2d9b954445.png)

### カテゴリ別収支推移画面

![kakeibo_analysis from 2019-02-20.png](https://qiita-image-store.s3.amazonaws.com/0/243199/a49e791a-74a4-6f22-872b-fad6c3026155.png)


## セキュリティ
かなり重要なところですが、ここはこだわりを持ってセキュリティの設定をしています。例えば、DDos攻撃、Syn flood、ステルススキャン、icmp攻撃などの対策をしています。
設定にはiptablesを使い、自分の手で調べつつ書きました。ssh接続のポートもしっかり22から別の番号にし、公開鍵秘密鍵の認証設定もしっかり行っています。
iptablesの機能にある、hashlimitを使用しているので、それぞれの送信者に対し制限をかけるようなファイアウォールを設定しています。

実際の設定内容は伏せますが、少しだけどんな対策をしているか紹介します。

### DDos攻撃
複数の箇所からアクセスしてくるような攻撃です。

```
-A INPUT -p tcp -m multiport --dport 80,443 -m state --state NEW -m hashlimit --hashlimit-name web_limit --hashlimit 60/m --hashlimit-burst 100 --hashlimit-mode srcip --hashlimit-htable-expire 360000 -j ACCEPT
```

### Syn flood攻撃
TCPの仕組みを利用した攻撃です。バックレみたいなやつなのでとても嫌いです。
詳しくはこちらを参照してください。
https://www.secomtrust.net/secword/synfloodat.html

```
-A INPUT -p tcp ! --syn -m state --state NEW -j DROP
```

### ステルススキャン
ステルススキャンは、ポートスキャンの強化版みたいなものです。相手にログを取られることなくポートスキャンができます。

```
-A INPUT -p tcp --tcp-flags ALL ALL -j DROP
```

### icmp攻撃
pingなどの通信確認でつかわれるようなプロトコルをicmpといいます。

```
-A INPUT -p icmp --icmp-type echo-request -m hashlimit --hashlimit-name t_icmp --hashlimit 1/m --hashlimit-burst 1 --hashlimit-mode srcip --hashlimit-htable-expire 120000 -j ACCEPT
```

### データを持たない接続
```
-A INPUT -p tcp --tcp-flags ALL NONE -j DROP
```

完璧とまではいかなくとも、かなり頑丈なWebアプリになったのではないでしょうか。

# 今後のDAIFUKU
まだまだ追加したい機能があるので、今後も様子を見つつ開発を進めていこうかと考えています。
近々DAIFUKUの開発を手伝ってくれるメンバーがジョインしてくれそうなので、さらに良いサービスができることに期待できそうです。
DAIFUKUのTwitterもあるので、メンテナンス情報や新着情報などはこちらでお知らせしていきます。

> DAIFUKU公式Twitter
https://twitter.com/daihukuxyz

# 参考
[https://codecondo.com/popular-websites-django/](https://codecondo.com/popular-websites-django/)
https://qiita.com/zabeth129/items/383fabb324f241fbd405
https://qiita.com/Ningensei848/items/e91fbeef5f03685a7a0b
https://www.heartcore.co.jp/lineup/mariadb/index.html
https://eng-entrance.com/linux-ubuntu-call

誤字脱字や他に間違いなどあれば、遠慮なく編集リクエストを送ってください。