Skip to content

Record / Server Side

DjangoとReact連携、API版

DjangoとReact連携、API版

Django+Vite(React) で「Hello from Django!」API を叩く構成

  • Django: /var/www/django-5/myproject
  • React(Vite): /var/www/django-5/frontend
  • 開発時は
  • Django: ポート8000(python manage.py runserver
  • React: ポート3000(npm run dev ---host 0.0.0.0 --port 3000

【1】Django側:超シンプルAPIエンドポイントを作る

1-1. アプリを決める

Djangoプロジェクトの構成イメージ:

/var/www/django-5/
├── myproject/
│   ├── [settings.py](http://settings.py)
│   ├── [urls.py](http://urls.py)   ← プロジェクトのURL設定
│   └── ...
├── myapp/
│   ├── [views.py](http://views.py)  ← ここにAPIビューを書く
│   ├── [urls.py](http://urls.py)   ← アプリごとのURL
│   └── ...
└── [manage.py](http://manage.py)

1-2. myapp/views.py に API ビューを追加

# myapp/[views.py](http://views.py)
from django.http import JsonResponse

def hello_api(request):
    data = {
        "message": "Hello from Django!",
        "env": "django-5",
    }
    return JsonResponse(data)

1-3. myapp/urls.py を編集

# myapp/[urls.py](http://urls.py)
from django.urls import path
from .views import hello_api

urlpatterns = [
    path('hello/', hello_api, name='hello_api'),
]

1-4. プロジェクトの myproject/urls.py にアプリを紐づけ

# myproject/[urls.py](http://urls.py)
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', [admin.site](http://admin.site).urls),
    path('api/', include('myapp.urls')),  # ← ここを追加 重要
]

これで以下のURLが有効になります:

  • http://<サーバIP>:8000/api/hello/{"message": "Hello from Django!", "env": "django-5"} を返す

API専用のプレフィックスを付けたい場合は両方あった方が管理しやすい

多くのプロジェクトでは、APIエンドポイントを明示的に /api/ 配下に配置します

  • メリット: フロントエンドとAPIを明確に分離できる
  • メリット: 将来的にAPIバージョニング(/api/v1//api/v2/)がしやすい
  • 推奨: React連携の場合は path('api/', include('myapp.urls')) を追加することをお勧めします

今回のケースでは、path('api/', include('myapp.urls')) を追加することで、Reactから /api/hello/ という明確なAPIエンドポイントにアクセスできるようになります。

1-5. 動作確認

cd /var/www/django-5
python [manage.py](http://manage.py) runserver 0.0.0.0:8000

別ターミナルから:

curl [http://](http://127.0.0.1:8000/api/hello/)<サーバIP>[:8000/api/hello/](http://127.0.0.1:8000/api/hello/)

JSON が返ってくれば Django 側OKです。

【2】CORS 設定(開発中のみ)

ポート8000のDjangoに、ポート3000のReactがアクセスするので、開発中はCORSを許可しておくと安心です。

2-1. ライブラリインストール

cd /var/www/django-5
source venv/bin/activate
pip install django-cors-headers

2-2. myproject/settings.py を編集

INSTALLED_APPS に追加:

INSTALLED_APPS = [
    # ...
    'corsheaders',
    # ...
]

MIDDLEWARE に追加(なるべく上の方):

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',  # ← できれば一番上か2番目
    '[django.middleware.security](http://django.middleware.security).SecurityMiddleware',
    # ...
]

開発用の許可設定(本番では外す想定):

CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000",
    "http://127.0.0.1:3000",
    # SSHトンネルや別ホスト名を使う場合はここに追加
]

AWS上のViteへ直接アクセスしている場合(例:http://django-5.usual.tools:3000)なら、それも足します:

CORS_ALLOWED_ORIGINS = [
    "http://django-5.usual.tools:3000",
    "http://localhost:3000",
]

【3】React(Vite) 側:API を叩いて画面に表示する

API表示用シンプル版

中身を一度、API表示用にシンプルに、API呼び出しとUI表示を一緒にします。

// django-5/frontend/src/App.jsx

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

function App() {
  const [message, setMessage] = useState('ロード中...')
  const [error, setError] = useState(null)

  useEffect(() => {
    // 開発中は Django の 8000 番ポートを直接叩く
    fetch('http://django-5.usual.tools:8000/api/hello/')
      .then((response) => {
        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`)
        }
        return response.json()
      })
      .then((data) => {
        setMessage(data.message)
      })
      .catch((err) => {
        console.error(err)
        setError(err.message)
      })
  }, [])

  return (
    <div style= padding: "24px", fontFamily: "sans-serif" >
      <h1>React & Django 連携テスト</h1>

      <section>
        <h2>Django からのメッセージ</h2>
        {error ? (
          <p style= color: 'red' >エラー: {error}</p>
        ) : (
          <p>{message}</p>
        )}
      </section>
    </div>
  )
}

export default App

コンポーネント分割版

現在の App.jsx には API呼び出しとUI表示が一緒になっています。これを以下のように分割して、コードの可読性と再利用性を向上させます。

frontend/src/
├── components/
│   ├── Counter.jsx
│   ├── TextInput.jsx
│   └── DjangoMessage.jsx // 今回追加
├── App.jsx
└── main.jsx

DjangoMessage.jsx を作成

Django APIからメッセージを取得して表示するコンポーネントを作ります。

// frontend/src/components/DjangoMessage.jsx

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

function DjangoMessage() {
  const [message, setMessage] = useState('ロード中...')
  const [error, setError] = useState(null)

  useEffect(() => {
    // Django の API エンドポイントを叩く
    fetch('http://django-5.usual.tools:8000/api/hello/')
      .then((response) => {
        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`)
        }
        return response.json()
      })
      .then((data) => {
        setMessage(data.message)
      })
      .catch((err) => {
        console.error(err)
        setError(err.message)
      })
  }, []) // 空配列 = 初回マウント時のみ実行

  return (
    <section style={{marginBottom: '24px'}}>
      <h2>Django からのメッセージ</h2>
      {error ? (
        <p style={{color: 'red'}}>エラー: {error}</p>
      ) : (
        <p>{message}</p>
      )}
    </section>
  )
}

export default DjangoMessage

App.jsx を簡潔に書き直す

App.jsx はコンポーネントを配置するだけのシンプルな構成にします。

// frontend/src/App.jsx

import React from 'react'
import DjangoMessage from './components/DjangoMessage'

function App() {
  return (
    <div style={{padding: '24px', fontFamily: 'sans-serif'}}>
      <h1>React &amp; Django 連携テスト</h1>
      <Counter />
      <TextInput />
      <DjangoMessage />
    </div>
  )
}

export default App

※ URL は環境に合わせて差し替えてください:

  • 同じマシンでブラウザを開いているなら → [http://127.0.0.1:8000/api/hello/](http://127.0.0.1:8000/api/hello/)
  • 外から [django-5.usual.tools](http://django-5.usual.tools) 経由でアクセスなら → [http://django-5.usual.tools:8000/api/hello/](http://django-5.usual.tools:8000/api/hello/)

【4】React 開発サーバー起動 → ブラウザで確認

cd /var/www/django-5/frontend
npm run dev -- --host 0.0.0.0 --port 3000

ブラウザで:

  • [http://django-5.usual.tools:3000](http://django-5.usual.tools:3000)
  • など、Vite 開いているURLにアクセス

画面に

  • 「React & Django 連携テスト」
  • 「Django からのメッセージ: Hello from Django!」

が出れば Step2 完了です。

Back to Discoveries