【学習記録】DRFとVueでTodoアプリ作成2 バックエンド実装

この記事の続きです。

programming-gogogogo.hatenablog.com

Django REST framework(DRF)とVue.jsでTodoリストを作っていきます。
こちらの動画を参考にしています。

www.youtube.com

前回までで環境構築とサーバーの起動まではできているので、下記コマンドを実行してsuperユーザーを作成します。

python manage.py createsuperuser

f:id:JunpeiNakasone:20210404162052p:plain (画像ではパスワードに簡単な文字列を設定したので警告が出ています)

次にフロントエンドの環境構築をします。

下記コマンドを実行してvueの新規プロジェクトを作成します。

vue create プロジェクト名

コマンドを実行すると初期設定を選択するので、自分は以下のように選択しました。
f:id:JunpeiNakasone:20210404162650p:plain

しばらくするとインストールが完了するので、以下のコマンドで画面が立ち上がります。

 cd vuengo_frontend
 npm run serve

ほかに必要なライブラリなどをインストールします。

npm install axios
npm install bulma

bulmaが正常にインストールされていることを確認するためにvuengo_frontend/src/App.vueに以下のコードを追加します。

    <button class="button is-primary">Primary Button</button>

その後npm run serveコマンドでフロントエンドのサーバーを立ち上げてブラウザからアクセスすると想定通りボタンがbulmaのスタイルで表示されていました。
f:id:JunpeiNakasone:20210404163606p:plain

次にバックエンドに戻り、以下のコマンドでディレクトリを追加します。

python manage.py startapp task

すると以下のようにディレクトリが追加されました。
f:id:JunpeiNakasone:20210404163921p:plain

まずモデルを定義するためにvuengo/task/models.pyを以下のように変更します。

from django.db import models

class Task(models.Model):
    TODO = 'todo'
    DONE = 'done'

    STATU_CHOICES = (
      (TODO, 'Todo'),
      (DONE, 'Done')
    )
    description = models.CharField(max_length=255)
    status = models.CharField(max_length=10, choices=STATU_CHOICES, default=TODO)

モデルを定義したら、またマイグレーションを行なってモデルをDBに反映させます。

マイグレーションを行う前にvuengo/settings.pyのINSTALLED_APPSにtaskを追加します。
f:id:JunpeiNakasone:20210404164544p:plain どうやらpython manage.py startapp~を実行した後はsettings.pyのINSTALLED_APPSにも追加する必要があるみたいです。

次に以下のコマンドでマイグレーションを行います。

python manage.py makemigrations
python manage.py migrate

f:id:JunpeiNakasone:20210404164826p:plain

次にvuengo配下にserializers.pyを新規作成し、以下のコードを入力します。

from rest_framework import serializers

from .models import Task

class TaskSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Task
        fields = ('id', 'description', 'status')

HyperlinkedModelSerializerとclass Metaがちょっと理解が曖昧だったので調べてみました。

公式ドキュメントのHyperlinkedModelSerializerについての説明は以下です。
www.django-rest-framework.org

The HyperlinkedModelSerializer class is similar to the ModelSerializer class except that it uses hyperlinks to represent relationships, rather than primary keys. By default the serializer will include a url field HyperlinkedModelSerializerクラスはModelSerializerクラスと似ているが、プライマリーキーではなくhyperlinkを使ってリレーションを表現する部分で異なっている、みたいな感じだと思いますがすぐにはピンとこなかったです。
とりあえずなんとなくのイメージだけ持っておいて手を動かしながら理解を深めていきたいと思います。

Class Metaについてもまだわからない部分が多いですが、以下の記事がわかりやすそうだったので時間を作って深掘りしていきたいです。

teratail.com

チュートリアルの方に戻ります。

vuengo/task/views.pyを以下の内容に修正します。

from django.shortcuts import render

from .models import Task
from .serializers import TaskSerializer

from rest_framework import viewsets
from rest_framework.authentication import BasicAuthentication
from rest_framework.permissions import IsAuthenticated

class TaskViewSet(viewsets.ModelViewSet):
    authentication_classes = (BasicAuthentication,)
    permission_classes = (IsAuthenticated,)
    queryset = Task.objects.all()
    serializer_class = TaskSerializer

次に動作確認のためデータをDBに投入します。
以下のコマンドでPythonのシェルを開きます。

python manage.py shell

対話型のシェルから以下のコマンドを実行しデータを投入します。

>>> from task.models import Task
>>> task1 = Task.objects.create(description='task number 1')
>>> task2 = Task.objects.create(description='task number 2')
>>> task3 = Task.objects.create(description='task number 3', status=Task.DONE)

次にTask.objects.all()で現在のTaskモデルのデータを取得します。

>>> tasks = Task.objects.all()
>>> tasks
<QuerySet [<Task: Task object (1)>, <Task: Task object (2)>, <Task: Task object (3)>]>

f:id:JunpeiNakasone:20210404215050p:plain

次にvuengo/urls.pyを以下の内容に修正します。

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

from task.views import TaskViewSet

from rest_framework import routers

router = routers.DefaultRouter()
router.register('tasks', TaskViewSet)

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

上記設定を完了した後、python manage.py runserverでサーバーを起動します。
その後以下のcurlコマンドでHTTPリクエストを送ります。

curl -H 'Accept: application/json; indent=4' -u admin:admin http://127.0.0.1:8000/tasks/

すると以下のレスポンスが返されます。

[
    {
        "id": 1,
        "description": "task number 1",
        "status": "todo"
    },
    {
        "id": 2,
        "description": "task number 2",
        "status": "todo"
    },
    {
        "id": 3,
        "description": "task number 3",
        "status": "done"
    }
]

次回でフロントエンドも実装していきます。