[Django REST Framework]でReactとのAPI連携


実行環境

MacOS BigSur -- 11.2.1
Python3 -- 3.8.2
Django -- 3.1.7
djangorestframework -- 3.12.2
npm -- 6.14.4
react -- 17.0.1
react-dom -- 17.0.1
axios -- 0.21.1

Django REST Framework(DRF) を始めてみる

これまでDjangoのみを用いたWebアプリケーションの作成をしていましたが、フロントエンドの高度化ができず、DRFを用いてReactと組み合わせてみたい!!!と思いました。Reactに関してはまだ知識が少ないのですが、とりあえずDRFで作成したAPIをReactに渡す部分を実装をしたのでその手順をメモがてらに記述します。

DRFの続き(バックエンド)

前回の記事⇨
https://qiita.com/kachuno9/items/52a756f15207f625f358
でカスタムユーザーによるDRFプロジェクト作成は終わっているのでその続きからです。
ちなみに、ディレクトリ構成はこんな感じです。

my_api
   ├── backend
   │   ├── __init__.py
   │   ├── admin.py
   │   ├── apps.py
   │   ├── migrations
   │   ├── models.py
   │   ├── serializers.py
   │   ├── tests.py
   │   ├── urls.py
   │   └── views.py
   ├── db.sqlite3
   ├── manage.py
   ├── media
   └── my_api
       ├── __init__.py
       ├── asgi.py
       ├── settings.py
       ├── urls.py
       └── wsgi.py

Model

とりあえず簡単にPostモデルを作成しました。

models.py
class Post(models.Model):
    title = models.CharField('タイトル', max_length=50)
    text = models.TextField('テキスト')
    created_at = models.DateField('作成日', auto_now_add=True)
    updated_at = models.DateField('更新日', auto_now=True)

    def __str__(self):
        return self.title

View

views.py
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from backend import serializers
from .models import Post

class PostAll(APIView):
    def get(self, request):
        try:
            post = Post.objects.all().order_by('-created_at')
            res_list = [
                {
                    'id': p.id,
                    'date': p.created_at,
                    'title': p.title,
                }
                for p in post
            ]
            return Response(res_list)
        except:
            return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)

URL関連

さて、簡単なモデルとビューを作成したのでURLを設定します。

my_api/urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf import settings

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/v1/', include('backend.urls'))
]
backend/urls.py
from django.urls import path
from backend import views

urlpatterns = [
    path('', views.PostAll.as_view()),
]

動作確認

仮想環境内で、サーバーを立ち上げます。

$ python3 manage.py runserver

http://localhost:8000/api/v1/
にアクセスすると、しっかりとAPIの動作確認が行えました。
ちなみにデータはadminサイトであらかじめサンプルようにいくつか追加しています。

Reactプロジェクト作成(フロント)

先程までとは別のターミナルを立ち上げて環境構築、プロジェクト作成を行います。アプリ名は「frontend」にしました。

$ npx create-react-app
$ cd frontend
$ npm install axios
$ npm install react-router-dom
$ npm start

するとReacrのロゴが表示されるページが出てきて、正常にプロジェクト作成できた事がわかります。
ちなみに、frontend/srcのディレクトリ構成はこの通りです。

frontend/src
   ├── App.css
   ├── App.js
   ├── App.test.js
   ├── index.css
   ├── index.js
   ├── reportWebVitals.js
   └── setupTests.js

ReactとDRFの連携

さて、いよいよDRFとの連携を行います。DRFでは
http://localhost:8000/api/v1/
でデータを取得できるようにしているので、React側でここにGetリクエストを送るように実装します。axiosを用いることで簡単にリクエストを実装できるということで、インストールしました。

App.js
import React, { Component } from 'react';
import axios from 'axios';

class App extends Component {
    state = {
        posts: []
    };

    componentDidMount() {
        this.getPosts();
    }

    getPosts() {
        axios
            .get('http://localhost:8000/api/v1/')
            .then(res => {
                this.setState({ posts: res.data });
            })
            .catch(err => {
                console.log(err);
            });
    }

    render() {
        return (
            <div>
                {this.state.posts.map(item => (
                     <div key={item.id}>
                        <h1>{item.title}</h1>
                        <p>{item.date}</p>
                     </div>
                ))}
            </div>
        );
    }
}

export default App;

http://localhost:3000/
にアクセスするとしっかりDRFからデータを受け取っている事が分かります!!

今回はDRFとReactの連携が確認できたところまでです。
これまでバックエンドとフロントエンドを分けて開発するといった高度な開発経験がなかったので、DRFとReactが連携できただけですごく嬉しかったです(笑)
Reactに関してはまだまだ知識が少なく、見よう見まねですがこれから開発を進めていきたいと思います!!

参考

以下のページが非常に分かりやすく、参考にさせていただきました。
- https://qiita.com/__init__/items/f5a5a64a05541fcda713#todo-api-%E3%81%AE%E6%A7%8B%E7%AF%89
- https://qiita.com/Piyopanman/items/5ffb9c290d452e0a5782
- https://qiita.com/Piyopanman/items/0a757a7b2dd412e07135