Django × Reactでハイブリッド株式管理アプリを構築する【環境セットアップ編】

株式管理アプリをDjangoとReactを組み合わせて構築していきます。
Djangoの堅牢なバックエンドとReactのインタラクティブなフロントエンドを組み合わせることで、効率的で使いやすいアプリケーションを実現できます。
本シリーズでは、株式の追加・編集・削除や株価情報の表示といった機能を備えた株式管理アプリを開発します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/7a2150ff-397f-0c95-c153-f7581ac0d4f7.png)


本記事ではその第一歩として、DjangoとReactの環境構築から始めていきます。

## プロジェクト構成
StockKeeper というDjangoプロジェクトを作成して開発していきます。
フォルダ/ファイル構成は以下とします(使用しないフォルダ/ファイルは無視)
```
StockKeeper
|－ config：Django プロジェクト設定
|－ equity_hub：Django 株式管理アプリ
|－ react-fronetnd：React フロントエンド用アプリ
|－ templates：Django HTMLテンプレート
|－ users：Django ユーザー管理アプリ
```

## ページ構成
DjangoのテンプレートとReactのハイブリットで構成します。
```
ログインページ：Django テンプレート
↓
ホーム：React
↓
株式分析：React
```

## Django プロジェクト作成
python venv を使用して仮想環境を使用してプロジェクトを作成します。
```sh
python -m venv StockKeeper <- 好きなプロジェクト名

cd StockKeeper

# 仮想環境を立ち上げる
./Scripts/Activate

# 仮想環境の中でDjangoをインストールする
pip install django

# Djangoのプロジェクトフォルダを作成する
django-admin startproject config .

# Djangoのユーザー管理用アプリを作成する
django-admin startapp users <- 好きなアプリ名

# Djangoの株式管理用アプリを作成する
django-admin startapp equity_hub <- 好きなアプリ名

# 動作確認
python manage.py runserver -> http://127.0.0.1:8000/ にアクセス
```

## アプリを登録
equity_hub と users を登録しておく
```py:config/settings.py
INSTALLED_APPS = [
    ...
    "equity_hub.apps.EquityHubConfig",
    "users.apps.UsersConfig",
]
```

## React プロジェクト作成
Django プロジェクト内に React typescript プロジェクトを作成する。
```sh
# Django プロジェクトフォルダ内で実行
npx create-react-app react-frontend --template typescript <- react-frontend 好きなプロジェクト名

# React プロジェクト内で動作確認
cd react-frontend
npm start -> http://localhost:3000/ にアクセス
```

## ライブラリのインストール
postgreSQL のインストールは別途行っておく
```sh
# postgreSQL を今回は使用
pip install psycopg2

# Rest API 用ライブラリ
pip install djangorestframework

# Django で React のwebpack読み込み用
pip install django-webpack-loader

# TypeScript を Webpack で扱うライブラリ
npm install ts-loader

# React URL管理ライブラリ
npm install react-router-dom

# webpack build用
npm install webpack-cli

# axiosをインストール
npm install axios --save-dev
```

インストールしたライブラリとReact用Static URL 設定
```py:config/settings.py
import os

INSTALLED_APPS = [
    ...
    "webpack_loader",
    "rest_framework",
]

STATIC_URL = "/static/"
STATICFILES_DIRS = [os.path.join(BASE_DIR, "react-frontend", "build", "static")]
```

## モデルの作成
株式情報を管理するモデルを作成
```python:StockKeeper/equity_hub/models.py
from django.db import models

class EquityHub(models.Model):
    stock_No = models.AutoField(primary_key=True) # 自動付与プライマリ
    symbol = models.CharField(max_length=10, unique=True) # 証券コード
    name = models.CharField(max_length=100) # 銘柄名
    dividend_yield = models.FloatField() # 配当利回り
    price = models.FloatField() # 現在値
    shares_owned = models.IntegerField() # 所持個数
    industry = models.CharField(max_length=100, null=True, blank=True) # 銘柄分類
    user = models.ForeignKey('auth.User', on_delete=models.CASCADE)

    def __str__(self):
        return self.name
```
## DBセッティング
事前に作成したDB名を NAME に入れてください。
```py:StockKeeper/config/settings.py
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql_psycopg2",
        "NAME": "stock_keeper",
        "USER": "postgres",
        "PASSWORD": "password",
        "HOST": "localhost",
        "PORT": "5432",
    }
}
```

## モデルのマイグレーション
```sh
# 作成したモデルをDBに登録
# モデルのマイグレーションファイルを作成する
python manage.py makemigrations

# マイグレーションを実行する
python manage.py migrate
```

## Reactのbuild設定
ホームと分析ページはReactで作成するのでbuild設定を行います。
react-frontend に webpack.config.js を作成してください。
```js:react-frontend/webpack.config.js
const path = require('path');

module.exports = {
    mode: 'development',
    entry: './src/index.tsx', //buildするファイル
    output: {
        filename: 'bundle.js', //build後のファイル名
        path: path.join(__dirname, './build/static/js') //buildファイルが作成される場所
    },
    module: {
        rules: [
			//JavaScriptの場合のloader設定
			{
				test: /\.js[x]?$/,  
				exclude: /node_modules/,
				use: {
					loader: 'babel-loader',
					options: {
						presets: [
							'@babel/preset-env',
							'@babel/preset-react' 
						],
						plugins: ['@babel/plugin-syntax-jsx'] 
					}
				}
			},
			//Typescriptの場合のloader設定
			{
				test: /\.ts[x]?$/,  
				exclude: /node_modules/,
				use: 'ts-loader',
			},
			//CSSファイルを読み込むための設定
			{
				test: /\.css$/,
				use: [
					'style-loader',
					'css-loader',
				],
			},
		],	
    },

    resolve: {
        extensions: ['.js', '.jsx', '.json', '.ts', '.tsx']
	}
};

```
react-frontend/build/static/js/bundle.js という名前で buildされたファイルが作成するように設定しました。

build でファイルが出力できるように "noEmit" を false に設定しておきます。
```json:react-frontend/tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": false,
    "jsx": "react-jsx"
  },
  "include": [
    "src"
  ]
}
````

## 終わりに
プロジェクトの作成と設定ができたので、次回は株式の追加機能実装を行っていきます。