はじめに##
Vue.jsが気に入ってしまったので、DjangoのQuerySetをJSON形式に変換してVue.js内で扱える様にしました。忘れっぽい自分のために、備忘録的に残します。
###前提条件###
Django: version 3.1.7
Vue.js: version 2.6.12(CDN)
axios等は使用しません
###コード###
Djangoにアプリ追加したところで各モジュールを書きかえます。
from django.urls import path
from . import views
app_name= 'app'
urlpatterns = [
path('list/', views.ListData, name= 'list'),
]
import uuid
from django.db import models
class Book(models.Model):
id= models.UUIDField(primary_key=True, default= uuid.uuid4, editable= False)
title= models.CharField(verbose_name= 'タイトル', max_length=40)
ここでは、JSONが知らない特別なタイプの型をとるために、idをUUIDにしておきます。
import json, uuid
class ListDataView(ListView):
template_name= "app/listdata.html"
model= Book
def get_context_data(self, **kwargs):
def cnvDataToJson(object):
if(isinstance(object, uuid.UUID)):
return str(object)
context= super().get_context_data(**kwargs)
books= self.object_list.values('id', 'title')
bookList= json.dumps(list(books), ensure_ascii=False, default=cnvDataToJson)
context["bookList"]= bookList
return context
ListData= ListDataView.as_view()
Bookモデルからデータを得る時に、**values()クエリを使って「辞書のリスト」に変換しておきます。
その後、この辞書リストをjson.dumps()**でJSON形式の配列に変換しますが、default=cnvDataToJsonのところで、jsonが知らない型を文字列に変換してあげるためのコールバックを設定します。
なお、ensure_ascii=Falseは文字バケ対策です。
<div id="v-app">
<button @click="get_books()">GetBooks</button>
<div>
<table>
<tr>
<th>No.</th>
<th>タイトル</th>
</tr>
<tr v-for="(book, index) in books">
<td>[[index]]</td>
<td>[[book.id]]</td>
<td>[[book.title]]</td>
</tr>
</table>
</div>
</div>
<script src="https://unpkg.com/vue@2.6.12/dist/vue.min.js"></script>
<script>
Vue.options.delimiters = ['[[',']]']
const vm = new Vue({
el: "#v-app",
data: function(){
return{
books:[],
}
},
methods:{
get_books: function(){
this.books.splice(0);
this.books= {{bookList|safe}}; //Djangoから受け取るデータを配列にセットする。
},
},
})
</script>
Vue.options.delimiters = ['[[',']]']
DjangoとVue.jsはデフォルトではテンプレート内で使用する{{ }}が衝突してしまうため、Vue.js側でデリミタを再定義してあげます。
this.books= {{bookList|safe}}
JSON配列となったデータをVue.js(javaScript)側の配列に移します。このときsafeでフィルタすることで、エクケープ処理をします。(細かいことは解りませんが、これがないとダメでした。)
###あとがき###
javaScriptからDjangoの{{ }}を扱う時にずっと" "で囲うことをしていたために欲しい結果が得られずにいました。
Djangoのテンプレートなので" "は要らないことが判りました。
あと、Htmlタグに仕掛けをすることが出きるVue.jsって素晴らしく便利だと思った。(CLIの方は敬遠します)