🟡

【Vue.js】DBの内容をセレクトボックスに表示させる

に公開

完成イメージ


DBの内容をフロントエンド(Vue)で表示させる

【前提】環境構築が完了していること

https://zenn.dev/code_journey_ys/articles/9dab988afbca82
https://zenn.dev/code_journey_ys/articles/a76166094f9e3c

ここから、Django側でモデル → シリアライザー → ビューの順で記述する。

1.【Django】モデルの作成

backend/api/models.pyの内容
backend/api/models.py
from django.db import models

// カテゴリーモデルを作成
class Category(models.Model):
    name = models.CharField(max_length=100)
    
    def __str__(self):
        return self.name

2.【Django】シリアライザーの作成

serializers.pyファイルを作成するコマンド(Windows)
New-Item backend/api/serializers.py
backend/api/serializers.pyの内容
backend/api/serializers.py
// Django のアプリ(例: myapp)が複数あるなら、それぞれのアプリに serializers.py を作るのが一般的
from rest_framework import serializers
from .models import Category ← モデルを読み込む

class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = ['id', 'name']

3.【Django】ビューの作成

backend/api/views.pyの内容
backend/api/views.py
from django.shortcuts import render
from rest_framework import viewsets
from .models import Category
from .serializers import CategorySerializer

# api/views.py
class CategoryViewSet(viewsets.ModelViewSet):
    queryset = Category.objects.all()
    serializer_class = CategorySerializer

4.【Django】2つのurls.pyの記述

①プロジェクトフォルダのurls.py
プロジェクトフォルダのurls.py(project_root/urls.py)
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('api.urls')), 
]

②アプリケーションフォルダのurls.py
アプリケーションフォルダのurls.py(app/urls.py)
# myapp/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import CategoryViewSet

router = DefaultRouter()
router.register(r'categories', CategoryViewSet)

urlpatterns = [
    path('', include(router.urls)),
]

5.【Django】マイグレーションの実行

マイグレーションの実行コマンド
makemigrationsの実行
docker-compose -f docker/compose/docker-compose.dev.yml exec backend python manage.py makemigrations
migrateの実行
docker-compose -f docker/compose/docker-compose.dev.yml exec backend python manage.py migrate

6.【Django】管理画面でデータの登録

まだ、スーパーユーザーを作成していない場合
管理者ユーザーの作成を行う
docker-compose -f docker/compose//docker-compose.dev.yml exec backend python manage.py createsuperuser
作成したモデルを管理者画面で操作できるように設定
frontend/api/admin.py
from django.contrib import admin
from .models import Category

@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
	pass
管理画面にて確認する
Django管理画面にアクセスする
localhost:8000/admin/


管理者画面にCategoryモデルが正しく表示されているかを確認

データを追加する


ログインしてデータを作成する

7.【Vue.js】拡張ディレクトリ構造へ


vueのディレクトリを管理しやすい構造へ

拡張ディレクトリにするために必要なインストールライブラリ一覧
拡張ディレクトリにするために実行するべきコマンド一覧(インストールライブラリ一覧)
// ※frontendディレクトリへ移動して実行する(node_modulesへ追加される)
$ npm install pinia # 状態管理ライブラリ
$ npm install axios  # API通信ライブラリ
$ npm install vue-router # Vueコンポーネント間のルーティングを簡単に設定できる
$ npm install element-plus # コンポーネント
拡張ディレクトリにするため必要なフォルダ・ファイル作成コマンド
フォルダ作成コマンド(Windows)
mkdir frontend\src\views, frontend\src\router, frontend\src\store, frontend\src\services, frontend\src\utils
ファイル作成コマンド(Windows)
$files = @(
    "frontend\src\components\Home.vue",
    "frontend\src\components\About.vue",
    "frontend\src\views\HomeView.vue",
    "frontend\src\views\AboutView.vue",
    "frontend\src\router\index.js",
    "frontend\src\store\index.js",
    "frontend\src\services\api.js",
    "frontend\src\utils\dateUtils.js"
)

foreach ($file in $files) {
    New-Item -Path $file -ItemType "file" -Force
}

詳細は記事参照
axiosとは

8.【Vue.js】ビューの作成

frontend/src/views/Home.vueの内容
frontend/src/views/Home.vue
<template>
  <div>
    <h1>Vue + Django + PostgreSQL</h1>
    <h2>セレクトボックスにDBの内容を表示させる</h2>
    <el-select v-model="selectedCategory" placeholder="カテゴリを選択" style="width: 240px">
      <el-option
        v-for="category in categories"
        :key="category.id"
        :label="category.name"
        :value="category.id"
      />
    </el-select>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import axios from 'axios'

const categories = ref([])
const selectedCategory = ref(null)

onMounted(async () => {
  try {
    const response = await axios.get('http://localhost:8000/api/categories/')
    categories.value = response.data
  } catch (error) {
    console.error('カテゴリ取得エラー:', error)
  }
})
</script>

<style scoped>
/* 必要に応じてスタイルを追加 */
</style>

9.【Vue.js】ルーティングの設定

ルーティングの設定
frontend/main.js
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import axios from 'axios';
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

const app = createApp(App);
app.config.globalProperties.$axios = axios;
app.use(router);
app.use(ElementPlus);
app.mount('#app');
frontend/src/router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/HomeView.vue';
import About from '../views/AboutView.vue';

const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About },
];

const router = createRouter({
  history: createWebHistory(),
  routes,
});

export default router;

10.【Vue.js】vite.config.jsの設定

vite.config.jsの設定
frontend/vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src'), // @ を src ディレクトリにエイリアス
    },
  },
  server: {
    host: true,         // 0.0.0.0 にバインドして外部アクセス許可
    port: 5173,         // 明示的にポート指定(任意)
    strictPort: true,   // ポート競合時にエラーにする
    watch: {
      usePolling: true, // Docker内でのファイル監視問題を回避(特に Windows や WSL)
    },
  },
})

Discussion