Django React アプリケーションの URL をマッピングする


Front 側 を React、 Back 側 を Django で アプリケーションを作成していて、Root URL のみ、Django の urls.py で Mapping したところ、404 エラーになります。

URL のマッピングは、react-router-dom を使用していて、Django 側には設定がなかったため、この挙動になるのですが、 リクエストは一旦、Root URL に飛ばして、React router側で然るべきハンドリングをしたい ためどのような設定をすればよいか調べてみました。
結果を以下に記載します。


Django の 設定

URL のルーティングは React に 任せて、Django では、どの URL でも Root URL に設定している テンプレートに遷移をさせたいです。設定方法を検索したところ以下、StackOverFLow の記事がヒットしました。

上記を見ると、urls.py に以下のように記載をすると、どの URL へのアクセスも、Root URL のテンプレートに遷移させることができるようで、実際に設定すると、上手く表示できるようになりました。

    url(r'^$', TemplateView.as_view(template_name='home/home_page.html'), name='home_page'),
    url(r'^(?:.*)/?$', TemplateView.as_view(template_name='home/home_page.html'), name='other_page'),

Django の url.pyは、記載した順序が優先順位となり、評価されるようなので、URLパターンに合致しない全てのページを Root URL に振り分ける場合は、url(r'^(?:.*)/?$', TemplateView.as_view(template_name='home/home_page.html'), name='other_page'), の記載を一番下に記載する必要があります。


react-router-dom の設定

Django で 全てのページを Root URL で設定している テンプレートに遷移するようにしました。
react-router-dom 側では、合致する URL がない場合は、404エラーとしたいです。
react-router-dom で、404 ページを返すには、<Route component={NoMatch}/> のように、path なしの、Route を定義すると、合致する path がない場合、遷移してくれます。
以下、Stack Overflow の記事に記載がありました。
* reactjs - react-router-dom v4 404 pageNotFoundnot working - Stack Overflow

ただ、上記だけだと、ステータスコードは 404 にはならないため、別途 404 エラーをステータスコードに設定する必要があります。
以下、404エラーコードを返す記載がありますが、サーバーサイドでのレンダリング時に効いてくる設定のようで、クライアント側で記載しても、404は返却されませんでした。
* javascript - How to let react router respond with 404 status code? - Stack Overflow


react-router-dom で404 ページを表示しつつ、404エラーコードを返す

最終的に以下の設定を行いました。

  • urls.py
    urls.py には、react-router-domで、記載している URL に対するマッピングを記載します。

        # the list:
        url(r'^$', TemplateView.as_view(template_name='home/home_page.html'), name='home_page'),
        url(r'^about/$', TemplateView.as_view(template_name='home/home_page.html'), name='other_page'),
        url(r'^post/.+/$', TemplateView.as_view(template_name='home/home_page.html'), name='other_page'),
    

  • 404.html の記述を、home/home_page.html と同様の記述に変更する
    404.html を、react の 呼び出しを行う記述に変更しました。
    Django は、デフォルトで、404 エラー発生時に、404.html を参照します。
    Django の 404 ページの設定については、以下の記事が参考になりました。
    Djangoで、404ページを作る - naritoブログ

  • react-router-dom の設定
    path を定義しない、Route の記述を追加しました。

    <Switch>
        <Route exact path="/" component={PostList}/>
        <Route exact path="/post/:slug" component={PostDetail}/>
        <Route exact path="/about" component={About}/>
        <Route component={NoMatch}/>
    </Switch>
    

  • NoMatch component の作成
    以下のような、NoMatch component を作成しました。

    import React, {Component} from "react";
    
    
    class NoMatch extends Component {
        render() {
            return (
                <div className="mainContainer">
                    404 Page Not Found...
                </div>
            );
        }
    }
    
    export default NoMatch;
    

  • settings.py のDebug を False して、insecure を付与して、サーバーを起動する
    404 ページのテストを行う際は、Debug を False にする必要があります。
    Debug を False にすると、static ディレクトリの探索の仕方も変わるため、insecure オプションを付与して、各プロジェクトのstatic ディレクトリを探索するようにします。

    # SECURITY WARNING: don't run with debug turned on in production!
    DEBUG = False
    
    python3 manage.py runserver --insecure           
    

これで、HTTPのレスポンスとして、404エラーコード返却され、react側で、404エラーページに遷移するようになります。
以上です。

コメント