LoginSignup
13
18

More than 5 years have passed since last update.

Django+Reactアプリケーション開発の準備 ルーティング設定とReactのビルド自動化

Last updated at Posted at 2018-10-10

はじめに

Djangoのプロジェクト内にReact appを作成するだけでは、それぞれ

  • Django => 8000 port
  • React => 3000 port

というポートで接続して確認することになります。

  • ReactのWelcomeページを8000番で表示
  • Bootstrapの適用
  • Reactのビルド自動化

までやりたいと思います。
(Djangoのサーバを起動したときに同時にビルドするようになります)

セットアップ

$ django-admin startproject project
$ cd project
$ create-react-app frontend
$ cd frontend
$ yarn run build

django project内にreact appを作成してビルドしました。
起動してみます。

$ ./manage.py runserver

このままの状態では、8000番ポートに出力されるのはdjangoプロジェクトのスタートページです。
まずこれをReactのWelcomeページにしたい。

ReactのWelcomeページを8000番で表示

設定ファイルを以下のように編集します。

project/settings.py

......

# DIRSを追記

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(BASE_DIR, 'frontend', 'build'),
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

......

STATIC_URL = '/static/'

# STATICFILES_DIRSを追記 
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'frontend', 'build', 'static'),
]

project/urls.py
from django.contrib import admin
from django.urls import path, re_path
from django.views.generic import TemplateView

urlpatterns = [
    path('admin/', admin.site.urls),

    re_path('.*', TemplateView.as_view(template_name='index.html')),
]

これで、以下のように8000番ポートでReactのWelcome画面にルーティングされるようになりました。

スクリーンショット 2018-09-15 0.44.47.png

Bootstrapを適用してみる

とりあえずgetbootstrap.comからproject/frontend/public/index.htmlにコピペ

project/frontend/public/index.html
<!doctype html>
<html lang="ja-jp">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">

    <title>Hello, world!</title>
  </head>
  <body>
    <!-- ここだけ追記 -->
    <div id="root"></div>
    <h1>Hello, world!</h1>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
  </body>
</html>

ビルドしてサーバ起動。

$ pwd
project/frontend

$ yarn run build

$ cd ../

$ ./manage.py runserver

ブラウザで確認。

スクリーンショット 2018-09-15 0.56.49.png

オッケ〜:thumbsup:

build自動化

このままわざわざfrontendに行ってbuildするのは面倒なので、runserverと同時にビルドするように設定します。
./manage.py runserver reactとしたとき、ビルドするようにします。
つまり、argv(argument vector:コマンドライン引数)の3つ目がreactのときにです。

manage.py
#!/usr/bin/env python
import os
import sys

if __name__ == '__main__':
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
    try:
        from django.core.management import execute_from_command_line
    except ImportError as exc:
        raise ImportError(
            "Couldn't import Django. Are you sure it's installed and "
            "available on your PYTHONPATH environment variable? Did you "
            "forget to activate a virtual environment?"
        ) from exc

# 以下追記

    try:
        if sys.argv[2] == "react":
            project_root = os.getcwd()
            os.chdir(os.path.join(project_root, "frontend"))
            os.system("yarn run build")
            os.chdir(project_root)
            sys.argv.pop(2)
        execute_from_command_line(sys.argv)
    except IndexError:
        execute_from_command_line(sys.argv)
    else:
        execute_from_command_line(sys.argv)

(例外処理しないと何故かsys.argv[2]なんてないと怒られます
print(sys.argv[2])で普通に出力されるのになんででしょう?教えてください...:bow_tone1:

適当にproject/frontend/public/index.htmlを編集して./manage.py runserver reactを実行してみましょう。

これだけでReactがビルドされて出力結果が変わっているはずです。

参考

https://www.youtube.com/watch?v=kmpY6g5hYZI を参考にしています。
というか結構そのまま日本語にしてます。

13
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
18