NishimiyaChang
@NishimiyaChang (西宮)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

[Django]404ページが表示されない

解決したいこと

学習中の身ゆえ、見当違いのご質問でしたらご容赦ください。
仮想サーバ上の配置したDjangoの静的ファイルにReactプロジェクトを配置する、といった方法でWebアプリケーションの作成をしています。サーバソフトにはApache2を用いています。
404ページに関連する仕様で行き詰ってしまいました。
解決方法を教えて下さい。

発生している問題・エラー

存在しないアドレス(例:https ://example.com/存在しないページ") にアクセスすると、空白ページが表示される。

該当するソースコード

プロジェクトの urls.py は以下のようになっています。

from django.contrib import admin
from django.urls import path, re_path
from django.conf.urls import include
from django.views.generic import TemplateView
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
	path('', TemplateView.as_view(template_name='index.html')),
	path('admin/', admin.site.urls),
	path('myapp/', include('myapp.urls')),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

urlpatterns += [
    re_path('', TemplateView.as_view(template_name="index.html")), 
]

自分で試したこと

urls.py の最終ブロック

urlpatterns += [
    re_path('', TemplateView.as_view(template_name="index.html")), 
]

の部は、子ページ(例:https ://example.com/page1")でリロードを行うと404ページに飛ばされてしまうために付しました。この記述を取り除くと想定した挙動(存在しないページでの404表示)を行えるのですが、今度は前述の問題(リロードによるページ読み込み失敗)が引き起こされてしまい、堂々巡りとなっています。

0

1Answer

亀レスですがDjangoのルーティングとReactのルーティングがうまく連携できていない可能性があります。

React側はreact-router-domでルーティングを行っている想定で記述します。

発生している問題・エラー

存在しないアドレスにアクセスすると空白ページが表示される問題は、react-router-domの設定によるものです。
react-router-domでは、定義されていないルートに対して何も表示しないことがあります。

Djangoの設定

現在の urls.py の設定では、re_path('', TemplateView.as_view(template_name="index.html")) が全てのリクエストをReactにルーティングしているため、Djangoの404エラーページが表示されなくなっています。

urls.py
from django.contrib import admin
from django.urls import path, re_path
from django.conf.urls import include
from django.views.generic import TemplateView
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
	path('', TemplateView.as_view(template_name='index.html')),
	path('admin/', admin.site.urls),
	path('myapp/', include('myapp.urls')),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

urlpatterns += [
-    re_path('', TemplateView.as_view(template_name="index.html"))
+    # Reactによる404をDjangoが処理する設定
+    # 動作は変わらないが正規表現でより具体的に表しています
+    re_path(r'^.*$', TemplateView.as_view(template_name="index.html"))
]

Reactの設定

react-router-domで404ページを表示するには、ルート設定にワイルドカードを追加します。

app.tsx
'use stric';
import React from 'react';
import { BrowserRouter, Route, Routes } from 'react-router-dom';

import { Home, Page1, Page2, NotFound } from './pages';

const App: React.FC<{}> = (props) => {
    return (
        <BrowserRouter>
            <Routes>
                <Route path='/' element={ <Home/> } />

                <Route path='/page1' element={ <Page1/> } />

                <Route path='/page2' element={ <Page2/> } />

                {/* 404ページ */}
                <Route path='*' element={ <NotFound/> } />
            </Routes>
        </BrowserRouter>
    );
};

こんな感じで存在しないページにアクセスした際にReactで404ページが表示されるようになると思います。

1Like

Comments

  1. @NishimiyaChang

    Questioner

    ご回答いただきありがとうございます!
    自身も手あたり次第試しこのようなアプローチで解決できたのですが、原因などを理解しないまま進めてしまっていたため大変参考になるご回答でした。
    クローズ忘れてしまっており申し訳ありません。今回はありがとうございました!

Your answer might help someone💌