Django + Vue.jsでシステム開発! (14)

Django+Vue.js
この記事は約16分で読めます。
記事内に広告が含まれます。

Python(Django)+Vue.js(Nuxt.js,Vuetify)を使ったシステムの開発です。

APIの開発中ですが、ちょっと後戻りします。
このシステムはデータベーステーブル1つしかない状態です。
しかし現実にはテーブルが1つなんてことはありえないので、一般的な構成の設計に少し変更します。

変更点は

  • テーブルを2つにしてアソシエーションの関係を作る
  • 管理画面内で連携した状態で2つのテーブルの内容を表示する

という感じです。
この仕組がわかれば大量のテーブルが有るシステムでも一つ一つのつながりは一緒です。
大規模システムではテーブル量が多く、それぞれのテーブルが別のテーブルとつながっているだけで、ひとつひとつは同じものです。

スポンサーリンク

テーブルの追加

venvMitsumori > mitsumori > api > models.py

from django.db import models

# Categoryモデルの作成
class Category (models.Model):
    # ラベル付け
    class Meta:
        verbose_name = "商品カテゴリー"
        verbose_name_plural = "商品カテゴリー"

    name = models.CharField('カテゴリー名', max_length=255)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    # このモデルのデフォルト返却値にnameを設定
    def __str__(self):
        return self.name

class Item (models.Model):
    class Meta:
        verbose_name = "商品"
        verbose_name_plural = "商品"

    # id = AutoField(primary_key=True)  # 自動的に追加されるので定義不要
    # category = models.IntegerField('カテゴリー') ←コメントアウト
    # 新たにcategoryという名前でCategoryモデルへのアソシエーション作成
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    name = models.CharField('商品名', max_length=255)
    description = models.TextField('詳細', max_length=1000)
    price = models.IntegerField('金額')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

管理画面にCategory項目を追加

venvMitsumori > mitsumori > api > admin.py

from django.contrib import admin
from .models import Item, Category  ←Categoryを追加
# Register your models here.

class CategoryAdmin(admin.ModelAdmin):  ←clasaを作成
    list_display = ('id', 'name',)

class ItemAdmin(admin.ModelAdmin):
    # リストに作成日を追加
    list_display = ('category', 'name',  'price', 'created_at')
    # リンクををカテゴリーと名前に設定
    list_display_links = ('category', 'name')
    # フィリターにカテゴリーを追加
    list_filter = ('category',)
    # 検索項目に名前を設定
    search_fields = ('name',)

admin.site.register(Item, ItemAdmin)

admin.site.register(Category, CategoryAdmin)

migrationデータの更新

この変更でテーブルが増え、それぞれ連携するようになったので
初期データも変わります。
それと、idに0が指定できない(P−KEYの制限)ため、商品のカテゴリーIDは1から始めます。

venvMistumori > mitsumori > api > fixtures > fixture.json

[
  {"model": "api.category","pk": 1,"fields": {"name":"CPU","created_at": "2020-01-20T00:00:00Z", "updated_at": "2020-01-20T00:00:00Z"}},
  {"model": "api.category","pk": 2,"fields": {"name":"マザーボド","created_at": "2020-01-20T00:00:00Z", "updated_at": "2020-01-20T00:00:00Z"}},
  {"model": "api.category","pk": 3,"fields": {"name":"ビデオカード","created_at": "2020-01-20T00:00:00Z", "updated_at": "2020-01-20T00:00:00Z"}},
  {"model": "api.category","pk": 4,"fields": {"name":"ストレージ","created_at": "2020-01-20T00:00:00Z", "updated_at": "2020-01-20T00:00:00Z"}},
  {"model": "api.category","pk": 5,"fields": {"name":"ケース","created_at": "2020-01-20T00:00:00Z", "updated_at": "2020-01-20T00:00:00Z"}},

  {"model": "api.item","pk": 1,"fields": {"category": 1, "name": "すごいCPU","description": "", "price" : 50000,"created_at": "2020-01-20T00:00:00Z", "updated_at": "2020-01-20T00:00:00Z"}},
  {"model": "api.item","pk": 2,"fields": {"category": 1, "name": "普通のCPU","description": "", "price" : 10000,"created_at": "2020-01-20T00:00:00Z", "updated_at": "2020-01-20T00:00:00Z"}},
  {"model": "api.item","pk": 3,"fields": {"category": 1, "name": "イマイチなCPU","description": "", "price" : 3000,"created_at": "2020-01-20T00:00:00Z", "updated_at": "2020-01-20T00:00:00Z"}},
  {"model": "api.item","pk": 4,"fields": {"category": 2, "name": "すごいマザーボード","description": "", "price" : 30000,"created_at": "2020-01-20T00:00:00Z", "updated_at": "2020-01-20T00:00:00Z"}},
  {"model": "api.item","pk": 5,"fields": {"category": 2, "name": "普通のマザーボード","description": "", "price" : 12000,"created_at": "2020-01-20T00:00:00Z", "updated_at": "2020-01-20T00:00:00Z"}},
  {"model": "api.item","pk": 6,"fields": {"category": 2, "name": "イマイチなマザーボード","description": "", "price" : 5000,"created_at": "2020-01-20T00:00:00Z", "updated_at": "2020-01-20T00:00:00Z"}},
  {"model": "api.item","pk": 7,"fields": {"category": 3, "name": "すごいビデオカード","description": "", "price" : 60000,"created_at": "2020-01-20T00:00:00Z", "updated_at": "2020-01-20T00:00:00Z"}},
  {"model": "api.item","pk": 8,"fields": {"category": 3, "name": "普通のビデオカード","description": "", "price" : 8000,"created_at": "2020-01-20T00:00:00Z", "updated_at": "2020-01-20T00:00:00Z"}},
  {"model": "api.item","pk": 9,"fields": {"category": 3, "name": "イマイチなビデオカード","description": "", "price" : 2000,"created_at": "2020-01-20T00:00:00Z", "updated_at": "2020-01-20T00:00:00Z"}},
  {"model": "api.item","pk": 10,"fields": {"category": 4, "name": "すごいSSD","description": "", "price" : 20000,"created_at": "2020-01-20T00:00:00Z", "updated_at": "2020-01-20T00:00:00Z"}},
  {"model": "api.item","pk": 11,"fields": {"category": 4, "name": "普通のHDD","description": "", "price" : 5000,"created_at": "2020-01-20T00:00:00Z", "updated_at": "2020-01-20T00:00:00Z"}},
  {"model": "api.item","pk": 12,"fields": {"category": 4, "name": "イマイチなSDカード","description": "", "price" : 800,"created_at": "2020-01-20T00:00:00Z", "updated_at": "2020-01-20T00:00:00Z"}},
  {"model": "api.item","pk": 13,"fields": {"category": 5, "name": "かっこいいケース","description": "", "price" : 12000,"created_at": "2020-01-20T00:00:00Z", "updated_at": "2020-01-20T00:00:00Z"}},
  {"model": "api.item","pk": 14,"fields": {"category": 5, "name": "普通のケース","description": "", "price" : 3000,"created_at": "2020-01-20T00:00:00Z", "updated_at": "2020-01-20T00:00:00Z"}},
  {"model": "api.item","pk": 15,"fields": {"category": 5, "name": "ダサいケース","description": "", "price" : 1500,"created_at": "2020-01-20T00:00:00Z", "updated_at": "2020-01-20T00:00:00Z"}}
]

一般的にはモデルの変更があった場合は以下のコマンドで反映させます

(venvMitsumori) % python manage.py makemigrations 
(venvMitsumori) % python manage.py migrate 

ですが、もしうまく行かなかったら
Databaseを作り直してから再度実行してみてください。

# MySQLコマンドでデータベースに入って実行
> drop database mitsumori_db;
> create database mitsumori_db char set=utf8mb4;

(一旦データベースを削除し、新たに作ります。)
データベースを作り直した場合は管理ユーザーも消えているので作り直してください。

(venvMitsumori) % python manage.py createsuperuser
Username (leave blank to use 'marosuke'): [管理者アカウント]
Email address: [管理者メールアドレス]
Password: [パスワード]
Password (again): [パスワード]
...
...
Superuser created successfully.

テーブルの作成が終わったらfixtureで初期データを投入します。

(venvMitsumori) % python manage.py loaddata fixture.json

以上でデータベースのアソシエーションは終わりです。
もっと複雑なテーブル構造も同じやり方で作成できます。

実行

では実行してどう変わったか確認します。

項目名ラベルが日本語表示

一覧にカテゴリー名が表示

商品登録や修正時にカテゴリー名で選択

などいろいろ使いやすくなったと思います。

コメント

タイトルとURLをコピーしました