環境構成(Django+Vue3+Vuetify+Axios)に沿った手順を順に説明します。
🌐 全体構成
vue_django/
│
├── project/ # Django プロジェクト
│ ├── settings.py
│ ├── urls.py
│ └── ...
├── app/ # Django アプリ
│ ├── views.py
│ ├── urls.py
│ └── models.py
│
├── frontenv/ # Vue3 + Vuetify + Axios
│ ├── package.json
│ ├── src/
│ │ ├── main.js
│ │ ├── App.vue
│ │ └── views/
│ ├── public/
│ └── vue.config.js
│
├── static/ # Django 側静的ファイル出力先
└── templates/ # Django 側 HTML テンプレート出力先
最初にDjangoの環境構築
プロジェクト名をprojectとし、アプリケーション名をappとして構築します。
mkdir vue_django
cd vue_django
python -m venv ./venv
source venv/bin/activate
pip install django django-restframework
django-admin startproject project
chmod +x ./manage.py
Vue 3 + Vuetify 環境構築
vueの環境を構築:
npm install @vue/cli
cd vue_django/
vue create frontend
Vue CLI v5.0.9
? Please pick a preset: (Use arrow keys)
❯ Default ([Vue 3] babel, eslint)
Default ([Vue 2] babel, eslint)
Manually select features
axiosとrouterの導入:
cd vue_django/frontend
vue add axios router
Vuetify 初期設定:
mkdir public
vue add vuetify
? Choose a preset:
Vuetify 2 - Configure Vue CLI (advanced)
Vuetify 2 - Vue CLI (recommended)
Vuetify 2 - Prototype (rapid development)
Vuetify 3 - Vite (preview)
❯ Vuetify 3 - Vue CLI (preview)
vue.config.jsを以下のように編集:
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
publicPath: "/",
outputDir: "../static",
assetsDir: "../static",
indexPath: "../templates/index.html",
transpileDependencies: true,
pluginOptions: {
vuetify: {
}
},
})
src/main.js
を以下のように編集:
// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import vuetify from './plugins/vuetify'
import { loadFonts } from './plugins/webfontloader'
loadFonts()
createApp(App).use(router)
.use(router)
.use(vuetify)
.mount('#app')
Vuetify + Axios で Django REST API にアクセスする例
src/views/SampleView.vue
を作成:
<template>
<v-container>
<v-card class="ma-5 pa-5">
<v-card-title>Sample API Call</v-card-title>
<v-card-text>
<v-btn color="primary" @click="callApi">Call Django API</v-btn>
<div class="mt-4">Response: {{ response }}</div>
</v-card-text>
</v-card>
</v-container>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import axios from 'axios'
const response = ref('')
onMounted(async () => {
try {
const res = await axios.get('//localhost:8000/api/v1/sample/')
response.value = res.data;
} catch (err) {
response.value = 'Error: ' + err.message
}
});
</script>
src/router/index.js
にルートを追加:
import { createRouter, createWebHistory } from 'vue-router'
import SampleView from '../views/SampleView.vue'
const routes = [
{
path: '/',
name: 'Home',
component: SampleView,
},
]
export default createRouter({
history: createWebHistory(),
routes,
})
Django 側の調整
すでに REST Framework と SampleAPIView
が動いているので、
Vue 側からアクセスできる状態です。
以下で確認可能:
# Django サーバ起動
./manage.py runserver 0.0.0.0:8000
# Vue 側開発サーバ起動
cd frontenv
npm run serve
Vue 側が http://localhost:8080
、Django が http://localhost:8000
→ vue.config.js の proxy 設定により /api/
は Django 側へ中継されます。
SQLite3 を用いたモデルデータのAPI化
データベースへアクセスするための管理者用のアカウントを作成します。パスワードが短すぎたりすると注意がでてvalidationをbypassして良いか聞いてきますがここではyします。
cd ./vue_django
./manage.py makemigrations
./manage.py migrate
./manage.py createsuperuser
ユーザー名 (leave blank to use 'user'): admin
メールアドレス: <省略可>
Password: admin
Password (again): admin
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.
app/models.py
例:
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.CharField(max_length=100)
published = models.DateField()
def __str__(self):
return self.title
app/serializers.py
を追加:
from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = '__all__'
app/views.py
に追加:
from rest_framework import status, viewsets
from rest_framework.views import APIView
from rest_framework.response import Response
from django.views.generic.base import TemplateView
from .models import Book
from .serializers import BookSerializer
class IndexView(TemplateView):
template_name = "index.html"
class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
class SampleAPIView(APIView):
def get(self, request):
return Response("OK", status=status.HTTP_200_OK)
app/urls.py
を更新:
from rest_framework import routers
from app.views import BookViewSet, IndexViewSet
router = routers.DefaultRouter()
router.register(r'books', BookViewSet)
urlpatterns = [
path('sample/', SampleAPIView.as_view(), name='sample'),
]
urlpatterns += router.urls
project/urls.pyを更新:
from django.contrib import admin
from django.urls import path, include, re_path
from django.conf import settings
from django.conf.urls.static import static
from app.views import IndexView
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/', include('app.urls')),
re_path(r"^.*$", IndexView.as_view()),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
DBマイグレーション:
cd vue_django/
./manage.py makemigrations
./manage.py migrate
動作確認:
GET http://127.0.0.1:8000/api/v1/books/
Vue 側で axios 経由で呼び出せます。
✅ まとめ
要素 | 技術 | 状況 |
---|---|---|
フロント | Vue3 + Vuetify | SPA構築OK |
通信 | Axios | Django REST Frameworkと通信 |
バックエンド | Django + DRF + SQLite3 | REST API提供 |
統合 | vue.config.js の proxy 設定 + Django IndexView | SPA統合OK |
まずはSampleAPIViewでOKを得て表示されるところまでを作りました。次はコードの中にあったBookViewSet/BookSerializerの中身を表示させるようなものを作って見ようと思います。
に、アクセスして以下の画面でタイトルと著者、発行年月日を何件か登録しておくとBookViewSetのコード作成時に出力が得られて動作確認がしやすいです。

あとは、Vue 側で CRUD 画面(一覧・追加・削除)を実装や、Django 側で認証(JWT / Session)対応などへ進めていってアプリケーションとして機能するものを作ってみようと思います。