Django × React ToDoアプリを再始動したら、仮想環境・Vite・Djangoサーバーで詰まった話

はじめに

ブログベースで進める

これが自分の真実

Django × ReactのTODOリストを進めよう

Django側の現状確認

↓ GitHubのリポジトリ

ローカルサーバーを起動する

ローカルで、以下のコマンドを叩く(ローカルサーバーを起動するため)

python manage.py runserver

Djangoが読み込めないエラーが発生

djangoがないというエラー

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?

仮想環境を再起動しても解決しない

仮想環境が起動していない可能性があるので、一度 deactivate する

deactivate

以下のコマンドで、仮想環境を再起動した

source venv/bin/activate

それでも、同じエラーが出た

venvの中にはDjangoが入っているように見えた

チャッピーに伝えると、仮想環境にDjangoが入っていないとのこと

しかし、実際の仮想環境には、Djangoが入っていた

これをチャッピーに伝えると、pythonがこのvenv(仮想環境)を見ていないのが原因だと思うとのこと

使用されているPythonの場所を確認する

一度、ターミナルを以下のコマンドで綺麗にしてから、

clear

チャッピーに提案された以下のコマンドを試してみた

which python

pyenv側のPythonが使われていた

今いるディレクトリではない方のPythonが表示された

/Users/hiroki/.pyenv/shims/python

以下の状態とのこと

以下のコマンドで、pipの場所も確認した

which pip

Pythonと同じだった

/Users/hiroki/.pyenv/shims/pip

pyvenv.cfgから原因を確認する

pyvenv.cfgというファイルのcommandが以下のようになっているのが原因だった

command = /Users/hiroki/.pyenv/versions/3.12.2/bin/python3 -m venv /Users/hiroki/programing_output/django_todo/venv

以下のコマンドで、現在地を確認する

pwd

my-todoというディレクトリを作成していた

/Users/hiroki/programing_output/my-todo/django_todo

仮想環境を作り直す

仮想環境を作り直すのが早いとのことなので、

以下のコマンドで、仮想環境を抜けて、

deactivate

以下のコマンドで、仮想環境を削除して、

rm -rf venv

以下のコマンドで、仮想環境を再インストールして、

python3 -m venv venv

以下のコマンドで、仮想環境を起動した

source venv/bin/activate

正しいvenvのPythonが使われていることを確認する

認識されているPythonの場所を以下のコマンドで確認した

which python

以下の結果が得られた(正しい結果)

/Users/hiroki/programing_output/my-todo/django_todo/venv/bin/python

この状態で、以下のコマンドを打つと、

python manage.py runserver

以下のような、モジュールが足りないというエラーが出た

ImportError: Couldn't import Django. 

足りないPythonパッケージをインストールする

以下のコマンドで、足りないモジュールを順番にインストールしていく

python -m pip install django

rest_frameworkが足りない

ModuleNotFoundError: No module named 'rest_framework'

そのまま、モジュール名を入力してもダメだった

ModuleNotFoundError: No module named 'rest_framework'

正しいコマンドはこちら

python -m pip install djangorestframework

これで、インストール完了した

Successfully installed djangorestframework-3.17.1

次に足りないのはこちら

ModuleNotFoundError: No module named 'corsheaders'

以下のコマンドだとダメだった

python -m pip install corsheaders  

以下が正解

python -m pip install django-cors-headers

Djangoサーバーの起動に成功

以下のコマンドが無事に通った

python manage.py runserver  

ローカルサーバーが案内された

Starting development server at http://127.0.0.1:8000/

トップページが404になる理由

このページ自体はアクセスできない

その理由は、トップページの設定をしていないから

/api/ と /api/tasks/ の動作確認

apiとapi/tasksは存在する

django_todo/urls.py で、以下の設定をしている

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('myapp.urls'))
]

以下が確認できたので、バックエンド側のAPIはOK

React側の現状確認

別ターミナルで、以下を行う

npm run dev

zshのcompaudit警告に対応する

別ターミナル(Mac標準搭載のターミナル)を開くと以下を聞かれた

Last login: Wed Jun 17 02:06:34 on ttys002
You have new mail.
zsh compinit: insecure directories, run compaudit for list.
Ignore insecure directories and continue [y] or abort compinit [n]? 

コマンド補完(Tab補完)で使うディレクトリの権限が緩すぎるので、安全性を確認してください という警告

以下のコマンドで、原因調査を行う

compaudit

こちらは、Tab補完で使うファイルやディレクトリの権限が安全かチェックするためのコマンド

その結果はこちら

There are insecure directories:
/usr/local/share/zsh/site-functions
/usr/local/share/zsh

これは、compauditがこれらのディレクトリを危険だと判断したということ

このディレクトリの権限が実際にどうなっているのかを以下のコマンドで確認する

ls -ld /usr/local/share/zsh
ls -ld /usr/local/share/zsh/site-functions

以下のようになっていた

drwxrwxr-x  3 hiroki  admin  96  6月 10  2021 /usr/local/share/zsh
drwxrwxr-x  4 hiroki  admin  128  5月 11  2025 /usr/local/share/zsh/site-functions

こちらは、グループ(admin)に書き込み権限があるから安全とは言えないという意味

以下のコマンドを実行して、修正する

chmod 755 /usr/local/share/zsh
chmod 755 /usr/local/share/zsh/site-functions

そして、変更が適用されたかどうかを以下のコマンドで確認する

ls -ld /usr/local/share/zsh
ls -ld /usr/local/share/zsh/site-functions

以下の結果になった

drwxr-xr-x  3 hiroki  admin  96  6月 10  2021 /usr/local/share/zsh
drwxr-xr-x  4 hiroki  admin  128  5月 11  2025 /usr/local/share/zsh/site-functions

drwxr-xr-xになっているので、OK

compaudit で何も表示されなかったので、危険なディレクトリは存在しない状態にすることができた

React画面にアクセスする

準備が整ったので、react_todo のディレクトリに移動する

hiroki@shibatahiroshitakanoiMac programing_output % cd my-todo
hiroki@shibatahiroshitakanoiMac my-todo % ls
django_todo	react_todo
hiroki@shibatahiroshitakanoiMac my-todo % cd react_todo

移動完了

hiroki@shibatahiroshitakanoiMac react_todo % 

ここで、npm run dev を行う

Reactが以下のURLからデータを取得できているかどうかを確認する

http://127.0.0.1:8000/api/tasks/

viteが起動した

  VITE v6.2.2  ready in 281 ms

  ➜  Local:   http://localhost:5173/

http://localhost:5173/ にアクセスできた

React Refresh preambleエラーが発生

開発者ツールを開くと、エラーが3件発生していた

以下のエラーはアプリ本体のエラーではないので、無視してOK

pwa-entry-point-loaded 404
favicon.ico 404

以下のエラーが問題

Uncaught Error: React refresh preamble was not loaded.
at TaskList.tsx:1

TaskList.tsxを確認する

src/components/TaskList.tsx

import { useState, useEffect } from "react";
import axios from "axios";

const API_URL = "http://127.0.0.1:8000/api/tasks/";

interface Task {
  id: number;
  title: string;
}

const TaskList: React.FC = () => {
  const [tasks, setTasks] = useState<Task[]>([]);

  useEffect(() => {
    axios.get<Task[]>(API_URL)
      .then(response => setTasks(response.data))
      .catch(error => console.error("Error fetching tasks:", error));
  }, []);

  return (
    <div>
      <h2>タスク一覧</h2>
      <ul>
        {tasks.map(task => (
          <li key={task.id}>{task.title}</li>
        ))}
      </ul>
    </div>
  );
};

export default TaskList;

再起動しても、以下のエラーは発生していた

TaskList.tsx:1 Uncaught Error: React refresh preamble was not loaded. Something is wrong.
    at TaskList.tsx:1:185

package.jsonを確認する

package.json

{
  "name": "react_todo",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc -b && vite build",
    "lint": "eslint .",
    "preview": "vite preview"
  },
  "dependencies": {
    "axios": "^1.8.2",
    "react": "^19.0.0",
    "react-dom": "^19.0.0"
  },
  "devDependencies": {
    "@eslint/js": "^9.21.0",
    "@types/react": "^19.0.10",
    "@types/react-dom": "^19.0.4",
    "@vitejs/plugin-react-swc": "^3.8.0",
    "eslint": "^9.21.0",
    "eslint-plugin-react-hooks": "^5.1.0",
    "eslint-plugin-react-refresh": "^0.4.19",
    "globals": "^15.15.0",
    "typescript": "~5.7.2",
    "typescript-eslint": "^8.24.1",
    "vite": "^6.2.0"
  },
  "proxy": "http://127.0.0.1:8000"
}

vite.config.tsを確認する

vite.config.ts

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'

// https://vite.dev/config/
export default defineConfig({
  plugins: [react()],
})

main.tsxを確認する

src/main.tsx

import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <App />
  </StrictMode>,
)

index.htmlを確認する

index.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + React + TS</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html>

node_modulesとpackage-lock.jsonを作り直す

コマンド実行が完了して、VITEが起動した

http://localhost:5173/ の検証ツールには、以下のエラーが発生していた

問題になっていた以下のエラーは出ていなかった

Uncaught Error: React refresh preamble was not loaded.
at TaskList.tsx:1

src/App.tsx

import TaskList from "./components/TaskList.tsx";

function App() {
  return (
    <div>
      <h1>タスク管理アプリ</h1>
      <TaskList/>
    </div>
  );
}

export default App

codexを利用したいと思う

ブラウザ側が古い状態を読み込んでいることが原因かもしれないとのこと

ブラウザキャッシュを削除してハード再読み込みする

キャッシュの消去とハード再読み込みを行った

画面真っ白の状態からは解放された

最後に残ったエラー

現在発生しているエラーは、4件

チャッピーに相談

ERR_CONNECTION_REFUSEDが発生

Djangoサーバーが停止していた

実際に停止していたことが確認できた

(venv) hiroki@shibatahiroshitakanoiMac django_todo % 

Djangoサーバーを再起動する

以下のコマンドを叩く

python manage.py runserver

起動した

Starting development server at http://127.0.0.1:8000/

React画面でタスク一覧の表示に成功

無事に、Reactの画面でタスク一覧が表示された

エラーは発生していなかった

今回学んだこと

今回の作業では、DjangoやReactそのものだけではなく、開発環境の仕組みについても多くの学びがあった。

まず、仮想環境を起動しているように見えても、実際にその仮想環境のPythonが使用されているとは限らないということを学んだ。

今回は、

which python

を実行したことで、venvではなくpyenv側のPythonが参照されていることに気付くことができた。

また、

which pip

pwd

を使って現在地や参照先を確認することの重要性も理解できた。

次に、Pythonで読み込むモジュール名と、pipでインストールするパッケージ名が異なる場合があることを学んだ。

例えば、

import rest_framework

で使用するモジュールは、

pip install djangorestframework

でインストールする必要がある。

同様に、

import corsheaders

は、

pip install django-cors-headers

でインストールする。

エラーメッセージをそのまま鵜呑みにするのではなく、パッケージ名を調べることが大切だと感じた。

また、404エラーが表示されたとしても、必ずしも問題が発生しているわけではない。

今回のDjangoではトップページが設定されていなかったため、

http://127.0.0.1:8000/

では404が表示されたが、

http://127.0.0.1:8000/api/tasks/

は正常に動作していた。

エラー内容を正しく読み解くことが重要だと改めて感じた。

さらに、React側で発生していたエラーの原因がReactではなく、ブラウザのキャッシュやDjangoサーバーの停止だったことも印象的だった。

目の前のエラーだけを見るのではなく、

「どのレイヤーで問題が発生しているのか」

を切り分けながら調査することの大切さを学ぶことができた。

今回の作業を通じて、

Django

API

React

ブラウザ

という全体の流れを以前より理解できたと思う。

次にやること

今回の目標だった、

「Django REST Frameworkで作成したAPIをReactから取得して画面に表示する」

という部分は達成できた。

次は、表示するだけではなく、実際にCRUD操作を実装していきたい。

まずはタスク追加機能を実装する。

React側でフォームを作成し、入力した内容をPOSTリクエストでDjangoへ送信する。

その後、完了・未完了の切り替え機能を実装する。

現在は一覧表示のみなので、

completed = True

への更新処理を行えるようにしたい。

さらに、不要になったタスクを削除できるようにする。

一覧表示

追加

更新

削除

まで実装できれば、一通りのCRUD機能が揃う。

その後は見た目の改善も行いたい。

現状は最低限の表示のみなので、

  • レイアウト調整
  • ボタンデザイン
  • フォームデザイン
  • レスポンシブ対応

などを行い、実際のアプリらしいUIへ近付けていく。

今回でDjangoとReactの接続部分は確認できた。

次のフェーズは、

「データを取得する」

から

「データを操作する」

へ進んでいきたい。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です