139
122

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

DjangoのページをReactで作る - Webpack4

Last updated at Posted at 2019-04-21

Djangoは認証やセッションなどが簡単に実装できて便利です。DjangoとReactでWebアプリを構築するときに、ReactでSPAアプリを作れば、Djangoのこのような利点を利用するのが難しくなります。SPAでの認証にはJWTなどを使うのが一般的で少し複雑になります。結論的に言えば、基本的なところはDjangoに全て任せるとして、特定のDjango のページ(Template)をリッチにするためだけに使うのが現実的だと思われます。本記事はこのような考えを実装するための最小限の知識をまとめたものです。以下の記事を参考にしつつ自分なりに再構築しました。

Tutorial: Django REST with React (Django 2.0 and a sprinkle of testing)
Webpack 4 Tutorial: from 0 Conf to Production Mode

**【追記 2019/07/28】**DjangoとReactをまずは独立した環境で開発し、最後に結合する方法を試した記事です。==> 「Reactアプリから Django Rest API を叩いてみる - Qiita」

#1.ReactプロジェクトとDjangoプロジェクトのディレクトリ構成

まずwebpack4(名前は任意)ディレクトリを作成しトップディレクトリとします。
webpack4ディレクトリにはReactアプリ構築環境を... つまりnpmプロジェクトやwebpack、babelの環境を構築します。またdjangoreactwebpack4というDjangoプロジェクトを作成します。

つまりトップディレクトリには以下の2つのファイル/ディレクトリが置かれます。

  • Reactアプリの環境
  • Djangoプロジェクト

treeで表示すると以下のようなディレクトリ構成になります。

webpack4ディレクトリ
├── bin
├── djangoreactwebpack4(Djangoプロジェクト)
├── include
├── lib
├── lib64 -> lib
├── node_modules
├── package-lock.json
├── package.json
├── pyvenv.cfg
└── webpack.config.js
djangoreactwebpack4(Djangoプロジェクト)
├── db.sqlite3
├── djangoreactwebpack4
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-36.pyc
│   │   ├── settings.cpython-36.pyc
│   │   ├── urls.cpython-36.pyc
│   │   └── wsgi.cpython-36.pyc
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── frontend
│   ├── __pycache__
│   │   ├── urls.cpython-36.pyc
│   │   └── views.cpython-36.pyc
│   ├── src
│   │   ├── components
│   │   └── index.js
│   ├── static
│   │   └── frontend ( ── main.js)
│   ├── templates
│   │   └── frontend
│   ├── urls.py
│   └── views.py
└── manage.py

#2.Djangoプロジェクト

それではPythonの環境を作ります。

python -m venv webpack4
source webpack4/bin/activate

作業領域を作成しdjangoをインストールします。

cd webpack4  # 作業領域のトップに移行
pip freeze   # インストール済みは空であることを確認
pip install django  # Djangoをインストール

Djangoプロジェクトを作成します

django-admin startproject djangoreactwebpack4
cd djangoreactwebpack4/

私の環境は、DjangoはRemoteサーバに構築していますので、サーバのドメイン名を入力してアクセスを許可します。

djangoreactwebpack4/settings.py
---
ALLOWED_HOSTS = ["www.mypress.jp"]
---

DBを初期化します。

python manage.py migrate

ここまででDjangoのアプリを立ち上げます。

python manage.py runserver 0:8080

http://www.mypress.jp:8080/ で、以下のような画面が表示されます。

image.png

#3.Django templates と React components

frontend という名前で Django Appを作成し、この template に React App を貼り付けます。

それではfrontendを作成します。

django-admin startapp frontend

frontendディレクトリ配下を以下のように使用します。

  • frontend/srcディレクトリにReact Appのソースを作ります。
  • frontend/templatesはDjangoのテンプレートディレクトリです。
  • frontend/staticはDjangoの静的ファイルのディレクトリです。
mkdir -p ./frontend/src/components
mkdir -p ./frontend/{static,templates}/frontend

INSTALLED_APPSにfrontendを追加します。

djangoreactwebpack4/settings.py
---
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'frontend',  # 追加
]
---

DjangoのURLとviewsを定義します。

djangoreactwebpack4/urls.py
from django.urls import path, include
urlpatterns = [
    path('', include('frontend.urls')),
]
frontend/urls.py.
from django.urls import path
from . import views
urlpatterns = [
    path('', views.index ),
]
frontend/views.py
from django.shortcuts import render
def index(request):
    return render(request, 'frontend/index.html')

以上のURLとviewsの定義で、http://www.mypress.jp:8080/ のアクセスで、以下のindex.htmlが呼び出されることになります。

frontend/templates/frontend/index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.2/css/bulma.min.css">
  <title>Django DRF - React : Quickstart - Valentino G. - www.valentinog.com</title>
</head>
<body>
  <section class="section">
    <div class="container">
          <div id="app" class="columns"><!-- React --></div>
    </div>
  </section>
</body>
{% load static %}
<script src="{% static "frontend/main.js" %}"></script>
</html>

{% static %} テンプレートタグは、静的ファイルの完全 URL を生成します。{% static "frontend/main.js" %} はmain.jsを指すURLです。後で説明しますが、webpack (babel)がindex.jsをコンパイルしてmain.jsをstaticファイルとして生成します。それをこのindex.htmlが読み込んで、id="app"にマウントされることになるわけです。ここがDjangoとReactの接点になります。

frontend/src/components/App.js
import React from "react";
import ReactDOM from "react-dom";
const App = () => {
  return (
    <div>
      <p>React here!</p>
    </div>
  );
};
export default App;
ReactDOM.render(<App />, document.getElementById("app"));
frontend/src/index.js
import App from "./components/App";

#4.Reactプロジェクト

最後にReactプロジェクトの環境を構築していきます。

webpack4ディレクトリ直下にて作業を行います。

npm init -y
npm i webpack --save-dev
npm i webpack-cli --save-dev

npm run build や npm run dev でReactのindex.jsをコンパイルしてmain.jsを吐き出すようにします。index.jsとmain.jsのディレクトリに注意してください。

package.json
---
  "scripts": {
    "dev": "webpack --mode development ./djangoreactwebpack4/frontend/src/index.js --output ./djangoreactwebpack4/frontend/static/frontend/main.js",
    "build": "webpack --mode production ./djangoreactwebpack4/frontend/src/index.js --output ./djangoreactwebpack4/frontend/static/frontend/main.js"
  },
---

npm run devは開発時に使います。吐き出されるmain.jsがデバッグに備えて見やすいものになっています。npm run buildは本番deploy時に使います。main.jsは圧縮された形です。

必要なパッケージをインストールします。

npm i @babel/core babel-loader @babel/preset-env @babel/preset-react babel-plugin-transform-class-properties --save-dev
npm i react react-dom prop-types --save-dev

babelの設定です。

.babelrc
{
    "presets": [
        "@babel/preset-env", "@babel/preset-react"
    ],
    "plugins": [
        "transform-class-properties"
    ]
}

webapackの設定です。

webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      }
    ]
  }
};

Reactアプリをコンパイルします。

npm run build

それではDjangoプロジェクトを起動しましょう。

cd djangoreactwebpack4
python manage.py runserver 0:8080

http://www.mypress.jp:8080/ で、以下のような画面が表示されます。

image.png

以上です。

139
122
2

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
139
122

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?