Vue.jsでDRF製APIにデータを送信する


以下の記事で作成したAPIに対して、今度はPOSTでデータを送信、データベースに登録したい。
JsfiddleのVue.jsからDRFで作成したapiにアクセスしたい

環境

book/models.py
from django.db import models
import uuid
from django.utils import timezone

# Create your models here.
class Book(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(verbose_name='タイトル', max_length=50)
    price = models.IntegerField(verbose_name='価格')
    created_at = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return self.title

また、Vue.jsはjsfiddle上に記載しています。

登録したいデータ

Bookテーブルに新規のデータとして、titleフィールドとpriceフィールドを登録したいです。
idとcreated_atは自動で追加されるのでスルーでOK。

Vue.jsを書いていく

html
<div id="app">
  <div>
    <h1>GET</h1>
    <p>タイトル : {{ results[1].title }}</p><hr>
  </div>

  <div>
    <h1>POST</h1>
    <h2>タイトル : {{ title }}</h2>
    <h2>¥{{ price }}</h2>
    <input v-model='title'>
    <input v-model='price'>
    <button v-on:click='postBook'>送信</button>
  </div>
</div>

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
javascript
new Vue({
  el: '#app',
  data: {
    results: [],
    title: '',
    price: '',
  },
  methods:{
    postBook: function(){
        console.log('Hello')
      axios.post('http://127.0.0.1:8000/apiv1/book/', 
      { title : this.title , price : this.price })
    }
  },
  mounted() {
    axios.get('http://127.0.0.1:8000/apiv1/book/')
    .then(response => {this.results = response.data})
 },
})

inputタグでv-modelディレクティブを使い、titleprice設定。
Vueインスタンスに同じ名前のdataオブジェクトを定義し、中身は空にしておきます。

methodsにpostBookを登録。buttonタグにv-onディレクティブを使い、登録します。

postBookメソッドでは、axios.post('一覧画面のエンドポイント', { フィールド名:データ, フィールド名:データ})とし、フィールドとそれに対するデータをPOSTしている。

ここまでで以下とおり。

送信する

送信を押すと...

追加されてます。

数字にカンマをつける

値段を表示する際にカンマをつけたい場合は、Vueインスタンス内にfilter作り、適用させたいテンプレートのマスタッシュにパイプ=|でfilterを適用させます。

vueインスタンス
  filters: {
    comma(value) {
      if (!value) return ''
      value = value.toString()
      return value.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
 }
 }
html
<h2>¥{{ price | comma }}</h2>