非同期でデータ取得する方法はたくさんあると思いますが、そのなかでaxiosを使って取得する方法を調べてみました。
データ取得は汎用ビューのDetailViewを使用します。
urls.py
todo/urls.py
from django.urls import path
from . import views
app_name = "report"
urlpatterns = [
...
# 通常のリクエスト
path('todo/detail/<int:pk>', views.TodoDetailView.as_view(), name="detail"),
# こちらが今回実装する非同期によるデータ取得のためのurl設定
path('api/todo/detail/<int:pk>', views.TodoApiDetailView.as_view(), name="api-detail"),
]
views.py
todo/views.py
from django.views.generic import DetailView
from .models import Todo
from django.forms.models import model_to_dict # 追加
from django.http import JsonResponse # 追加
# 通常のリクエスト
class TodoDetailView(DetailView):
model = Todo
template_name = "todo/detail.html"
context_object_name = 'todo'
# こちらが今回実装する非同期によるデータ取得
class TodoApiDetailView(DetailView):
model = Todo
def get(self, request, *args, **kwargs):
obj = model_to_dict(self.get_object())
return JsonResponse(obj)
-
obj = model_to_dict(self.get_object())
- オブジェクトをdict形式に変換
-
from django.forms.models import model_to_dict
が必要
-
return JsonResponse(obj)
- JSON形式でレスポンス
-
from django.http import JsonResponse
が必要
テンプレートからデータ取得してみる
テンプレートにCDNを追加
templates/base.html
<html>
<head>
...
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<div class="container">
{% block content %}{% endblock %}
</div>
</body>
</html>
todo/detail.html
{% extends "base.html" %}
{% block content %}
<script>
window.onload = function() {
axios
.get('/api/todo/detail/1') // pk:1で仮設定しています
.then(response => {
// 成功
const data = response.data;
console.log(data); // json形式になっています
})
.catch(error => {
// エラー
console.error(error);
})
.finally(() => {
// 最終処理
});
};
</script>
{% endblock %}