LoginSignup
7
7

ReactとDjangoの連携したアプリを作ろう(Typescript & TailwindCSS & python)

Last updated at Posted at 2023-11-02

前書き

ReactとDjangoを連携したアプリを作成する手順です。

フロントエンドではTypescript、Tailwind CSSを使い、バックエンドではpythonを使用する。

本文は、使った技術の設定を中心に記載している。

1. Django(バックエンド)の基本設定

本文は https://qiita.com/shiranon/items/8182445975dff4cf19a6 (DjangoとReactの構築及びAPI連携について~構築編~) を一部参考した。

Djangoをインストールする

$ pip3 install django

rest_frameworkインストール

$ pip3 install djangorestframework

Djangoのプロジェクトを作成する

$ django-admin startproject <projectName>
本文ではプロジェクトの名前をbackendとする。なので、$ django-admin startproject backend を実行する。

デフォルトのファイル

コマンドを実行すると、プロジェクトの名前でディレクトリが作成される。
その中身は以下の通り。(△は編集する必要があるもの)

projectName
├─ manage.py        【プロジェクト管理、App作成、データ管理など】
└─ projectName      
	├─ __init__.py
	├─ settings.py  【△プロジェクトの構成】
	├─ urls.py      【△URLを関数に対応】
	├─ asgi.py      【リクエスト処理】
	└─ wsgi.py      【リクエスト処理】

Appを作成する

$ python manage.py startapp <AppName>
本文ではAppの名前をAppとする。
その他に、Api作成用のAppも作成する。
なので、

$ python manage.py startapp app
$ python manage.py startapp api

を実行する。

デフォルトのファイル

コマンドを実行すると、Appの名前でディレクトリが作成される。
その中身は以下の通り。

App
├─ __init__.py
├─ admin.py          【デフォルトのadmin管理者】
├─ apps.py           【app起動】
├─ migrations        【DB変更記録】
|	└─ __init__.py
├─ models.py         【△DBに対する操作】
├─ tests.py          【Unitテスト】
└─ views.py          【△関数】

APPを登録する

Appを作成したら、プロジェクトのsettings.pyに作成したAppを登録する必要がある。
ここで、rest_frameworkも登録する。

settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app', #追加
    'api.apps.ApiConfig', #追加
	'rest_framework', #追加
]

URLとview関数との関係の設定

ブラウザからURLでウェブページを表示するには、URLとview関数との関係を設定する必要がある。

Appディレクトリでurls.pyを作成する。

from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
]

プロジェクトのurls.pyを編集する。

from django.urls import include, path # includeを追加

urlpatterns = [
    path('admin/', admin.site.urls), デフォルトの管理者画面
    path('app/', include('app.urls')),
]

Appのviews.pyを編集する。

from django.shortcuts import render, HttpResponse
def index(request):
    return HttpResponse("Hello, world")

指定したurlにアクセスすると、viewsでの関数が呼び出されるという仕組みである。

ここではlocalhost:8000/index/にアクセスすると、Hello, worldと表示されるようになる。

サーバー起動

manage.pyがあるディレクトリで、以下のコマンドを実行する。

$ python manage.py runserver 8000

デフォルトのポート番号は8000番なので、ポート番号を指定せずに$ python manage.py runserverでも起動できるが。

ボート番号を指定したい場合は、$ python manage.py runserver <port番号>のようにする。

これでDjangoの基本的な設定は完了した。

2. APIを作成する

データベースを準備する

具体的なDjangoでデータベースを操る方法はこちら:https://qiita.com/shintake_heito/private/6362c008004d97d3eeda

今回はAPI化したDBを準備する。

Appのmodels.pyを編集する。

from django.db import models
# Create your models here.

class User_Model(models.Model):

    class Meta:
        db_table = 'User'

    user_id = models.CharField(
        verbose_name='userid',
        blank=True,
        null=True,
        max_length=225,
        default='',
    )

    user_name = models.CharField(
        verbose_name='username',
        blank=True,
        null=True,
        max_length=225,
        default='',
    )

    user_email = models.CharField(
        verbose_name='useremail',
        blank=True,
        null=True,
        max_length=225,
        default='',
    )

    def __str__(self):
        return self.user_id

ここで、user_id、user_name、user_emailの3つの項目を作成した。

manage.pyでmigrationを行う

$ python manage.py makemigrations
$ python manage.py migrate

管理画面からデータ投入を行うのでadmin.pyに記載する。

from django.contrib import admin
from .models import User_Model

admin.site.register(User_Model)

管理サイトに入るためのスーパーユーザ作成する。

python manage.py createsuperuser

スーパーユーザを作成したら、localhost:8000/admin/にアクセスし、ログインする。

django_admin_page_login.png

データを投入する。
django_input_data.png

DBシリアライズ化の設定

次にDBのシリアライズ化を行う。
apiアプリフォルダにserializers.pyを作成し、以下のように記載する。

from rest_framework import serializers
from app.models import User_Model


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User_Model
        fields = ('user_id', 'user_name','user_email')

apiアプリフォルダのviews.pyを以下のように記載する。

from rest_framework import viewsets, routers
from app.models import User_Model
from .serializers import UserSerializer

class UserApi(viewsets.ModelViewSet):
    queryset = User_Model.objects.all()
    serializer_class = UserSerializer

    def get_queryset(self):
        queryset = User_Model.objects.all()
        L_id = self.request.query_params.get('id')
		# queryでidを受けるとidでDBに検索をかけるようにしている。

        if L_id:
            queryset = queryset.filter(user_id=L_id)
        return queryset

router = routers.DefaultRouter()
router.register(r'user', UserApi)

ルーティングの設定

プロジェクトのurls.pyを以下のように記載する。

from django.contrib import admin
from django.urls import include, path
from api import views as api_views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('app/', include('app.urls')),
    path('api/', include(api_views.router.urls)), #追加
]

これで、APIの準備は完了した。

runserverし、http://localhost:8000/<apiアプリ>にアクセスすると、DBのデータが表示される。

3. React(フロントエンド)の設定

Reactのプロジェクトを作成し、TailwindCSSを使用する。

Reactのプロジェクトを作成する

$ npm create-react-app <projectName>
本文ではプロジェクトの名前をfrontendとする。なので、$ npm create-react-app frontend を実行する。

TypescriptベースのReactプロジェクトを作成

Typescriptを使用したReactプロジェクトを作成するには

create-react-app <projectName> --template typescript コマンドを実行する

ここで、--template typescript でtypescriptのテンプレートを指定する

TailwindCSSの使用

create-react-appではPostCSSの設定、postcss-importなどの重要なツールの設定に対応しないため、 Vite, Parcel, Next.js, or Remix でプロジェクトを作成するのをTailwindCSS公式では推奨している。(具体的なやり方はTailwindCSSドキュメントを参照、例:https://tailwindcss.com/docs/guides/vite)

エラー出る可能性あるので、「build時のエラー対応」の節に参照してください。

しかし、create-react-appで作成したプロジェクトでもTailwindCSSを使用することは可能である。
インストール手順は以下の通り。
1

$ npx create-react-app my-project
$ cd my-project

2

npm install -D tailwindcss
npx tailwindcss init

3
tailwind.config.jsを設定する

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

4
index.cssを作成する
./src/index.cssに以下のように記載する。

@tailwind base;
@tailwind components;
@tailwind utilities;

これでTailwindCSSの設定は完了した。

4. ReactとDjangoとの連携

Django側でindex.html作成

Django側のアプリのディレクトリにtemplatesフォルダを作成し、その中にindex.htmlを作成する。

<!DOCTYPE html>

{% load static %}

<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Reactアプリ</title>
</head>
<body>
    <div id="root"></div>
    <script type="text/javascript" src="{% static 'js/bundle.js' %}" ></script>
</body>
</html>

ここで、Bodyの内容はstatic/js/bundle.jsから読み込むようにしている。
bundle.jsはReactのビルドファイルで、React側でbuildを行うと作成される(React側での設定が必要)。

React側で必要なモジュールをインストールする

JavaScriptの場合には、babel-loaderを使用するが、TypeScriptの場合には、ts-loaderを使用する。

JavaScript: $ npm install --save-dev babel-loader

TypeScript: $ npm install --save-dev ts-loader

React側でwebpack.config.jsを作成

const path = require('path');

module.exports = {
    mode: 'development',
    entry: './src/index.js', //buildするファイル
    output: {
        filename: 'bundle.js', //build後のファイル名
        path: path.join(__dirname, '../django_react/react_app/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',
			},

		//TailwindCSSファイルを読み込むための設定
			{
				test: /\.css$/,
				use: [
					'style-loader',
					'css-loader',
					{
						loader: 'postcss-loader',
						options: {
							postcssOptions: {
								ident: 'postcss',
								plugins: [
									require('tailwindcss'),
									require('autoprefixer'),
								],
							},
						},
					},
				],
			},
		],	
    },

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

.envファイルを作成

パッケージ間の依存関係のチェックをスキップするようにするのである。
.envファイルを作成して下記のように記載する。

SKIP_PREFLIGHT_CHECK=true

build

buildしてみる。

$ npx webpack でnpm scriptによらず、直接webpackコマンドを実行する。(npm 5.2+ )

build時のエラー対応

エラー内容:TypeScript emitted no output for…

Module build failed (from ./node_modules/ts-loader/index.js):
Error: TypeScript emitted no output for...

対応法
tsconfig.jsonファイルをチェック

  1. noEmit がtrueの場合、 TypeScriptはファイルを生成しない。
    {
    	"compilerOptions": {
    		// ...
    		"noEmit": false,
    		// ...
    	}
    }
    
  2. sourceMapの生成を禁止する
    {
    	"compilerOptions": {
    		// ...
    		"sourceMap": false,
    		// ...
    	}
    }
    

TailwindCSSのエラー

ERROR in ./src/index.css 1:0
Module parse failed: Unexpected character '@' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> @tailwind base;
| @tailwind components;
| @tailwind utilities;

対応手順

  1. 必要とされるloadersとPostCSSをインストールする

    1. npm: $ npm install style-loader css-loader postcss-loader tailwindcss postcss autoprefixer --save-dev
    2. yarn: $ yarn add style-loader css-loader postcss-loader tailwindcss postcss autoprefixer --dev
  2. webpackを設定
    webpack.config.jsに以下を追加する。

     module: {
         rules: [
     	//TailwindCSSファイルを読み込むための設定
     	{
     		test: /\.css$/,
     		use: [
     			'style-loader',
     			'css-loader',
     			{
     				loader: 'postcss-loader',
     				options: {
     					postcssOptions: {
     						ident: 'postcss',
     						plugins: [
     							require('tailwindcss'),
     							require('autoprefixer'),
     						],
     					},
     				},
     			},
     		],
     	},
     	],	
     },
    
  3. PostCSSファイルを設定する

    1. postcss.config.jsがない場合は、Reactプロジェクトのディレクトリで作成する。
    2. TailwindCSSとAutoprefixer設定を以下のように記入する
    module.exports = {
     	plugins: {
     		tailwindcss: {},
     		autoprefixer: {},
     	},
     }
    

5. ReactでAPIを叩く

Axiosをインストール

ReactでAPIを叩くためのライブラリをインストールする。
$ npm install axios

エラー対応

下記のエラーが出る可能性がある。

npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR! 
npm ERR! While resolving: react-scripts@5.0.1
npm ERR! Found: typescript@5.2.2

対応法として、package.jsonのdependenciesに記載されているバージョンを変更する。
package.jsonに下記のように追加して記載する

"overrides": {
  "typescript": "^5.2.2",
},

APIを叩く

Reactのコンポーネントの中でaxiosを使用してAPIを叩く。

import React, {useState, useEffect} from 'react';
import axios from 'axios';


const Content = () => {
    interface User {
        user_id: string;
    }

    const [userInfo, setUserInfo] = useState<User[]>([]);

    useEffect(() => {
        axios.get('http://localhost:8000/api/user/')
            .then(res => {
                setUserInfo(res.data);
            });
    }, []);

    return (
        <div>
            <div>
                {userInfo.map(user => <div key={user.user_id}>{user.user_id}</div>)}
            </div>
        </div>
    );
}

export default Content;

ここで、axiosでAPIにアクセスし、DBのデータを取得し、そのデータを画面に表示している。

以上でReactとDjangoの連携は完了した。

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