【学習記録】DRFとVueでTodoアプリ作成4

この記事の続きです。

programming-gogogogo.hatenablog.com

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

www.youtube.com

前回まででDRFでもバックエンドの実装とVue.jsのフロントエンドでデータ取得まではできました。

そこにPOSTメソッドでのTodoタスクの新規作成と、PUTメソッドでTodoタスクのステータス更新を行えるようにするためVue.jsのsrc/views/Home.vueを以下のように修正します。

<template>
  <div class="home">
    <h1 class="title">Vuengo</h1>
    <hr>
    <div class="columns">
      <div class="column is-3 is-offset-3">
        <form v-on:submit.prevent="addTask">
          <h2 class="subtitle">Add Task</h2>

          <div class="field">
            <label class=label>Description</label>
            <div class="control">
              <input class="input" type="text" v-model="description">
            </div>
          </div>

          <div class="field">
            <label class="label">Status</label>
            <div class="control">
              <div class="select">
                <select>
                  <option value="todo">To do</option>
                  <option value="done">Done</option>
                </select>
              </div>
            </div>
          </div>

          <div class="field">
            <div class="control">
              <button class="button is-link">Submit</button>
            </div>
          </div>
        </form>
      </div>
    </div>

    <div class="columns">
      <div class="column is-6">
        <h2 class="subtitle">Todo</h2>

        <div class="todo">
          <div class="catd" v-for="task in tasks" v-bind:key="task.id">
            <div v-if="task.status == 'todo'">
              <div class="card-content">
              {{ task.description}}
            </div>
            <footer class="card-footer">
              <a class="card-footer-item" @click="setStatus(task.id, 'done')">Done</a>
            </footer>
          </div>
          </div>
        </div>
      </div>
        <div class="column is-6">
          <h2 class="subtitle">Done</h2>
          <div class="done">
            <div class="card" v-for="task in tasks" v-bind:key="task.id">
              <div v-if="task.status === 'done'">
                <div class="card-content">{{ task.description }}</div>
                <footer class="card-footer">
                  <a class="card-footer-item" @click="setStatus(task.id, 'todo')">Todo</a>
                </footer>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
</template>

<script>

import axios from 'axios'

export default {
  name: 'Home',
  data () {
    return {
      tasks: [],
      description: '',
      status: 'todo'
    }
  },
  mounted () {
    this.getTasks()
  },
  methods: {
    getTasks() {
      axios({
        method: 'get',
        url: 'http://127.0.0.1:8000/tasks/',
        auth: {
          username: 'admin',
          password: 'admin'
        }
      }).then(response => this.tasks = response.data
      )
    },
    addTask() {
      if (this.description) {
        axios({
          method: 'post',
          url: 'http://127.0.0.1:8000/tasks/',
          data: {
            description: this.description,
            status: this.status
          },
          auth: {
            username: 'admin',
            password: 'admin'
          }
        }).then((response) => {
          let newTask = {
            'id': response.data.id,
            'description': this.description,
            'status': this.status
          }

          this.tasks.push(newTask)

          this.description = ''
          this.status = 'todo'
        }).catch((error) => {
          console.log(error)
        })
      }
    },
    setStatus(task_id, status) {

      const task = this.tasks.filter(task => task.id === task_id)[0]
      const description = task.description

      axios({
        method: 'put',
        url: 'http://127.0.0.1:8000/tasks/' + task_id + '/',
        headers: {
          'Content-Type': 'application/json',
        },
        data: {
          status: status,
          description: description
        },
        auth: {
          username: 'admin',
          password: 'admin'
        }
      }).then(() => {
        task.status = status
      })
    }
  }
}
</script>

<style lang="scss">
.select, select {
  width: 100%;
}

.card {
  margin-bottom: 20px;
}

.done {
  opacity: 0.3;
}
</style>

コードを修正後、ブラウザにアクセスするとタスクの新規追加と既に作成されているタスクのステータス更新が行えるようになっていることが確認できました。

f:id:JunpeiNakasone:20210405225138p:plain

チュートリアルの写経は以上になります。
今回の目的はDRFでバックエンドを構築できるイメージを掴むことだったので、けっこう良い手応えがあります。

ModelViewSetでCRUD処理を一気に実装できるのはかなり開発のスピード上げれそうなので、もっと使いこなせるようになりたいですね。

不慣れな技術に慣れるためには大きい開発を一つ取り組むよりも小さい簡単なアプリをたくさん作ったほうが、自分の中でその技術の使い方とか頻出パターンを整理できるので、あと何個か勉強になりそうな動画を探して取り組んでみたいと思います。