2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【初心者向け】DjangoのFixtureについて一から徹底解説

Last updated at Posted at 2022-10-23

前提

  • DBはMySQLを使用

fixtureとは?

Djangoに備わっている初期データやテスト用データを用意する機能のことです
fixtureを使うことで

  • DjangoのAdmin画面から一つずつ手動で入力せずにコマンド一つでデータを投入できる
  • Gitで管理すればチームメンバーも同じデータをすぐに投入できる
  • fixtureのデータをテストコードのデータとしても流用できる

などメリットが大きいのでぜひ使いましょう!

サンプルモデル

fixtureの説明用に簡単なModelを作成しました

  • Author1人に対してBookは複数あるのでOneToMany
  • Book複数に対してCustomerは複数存在するのでManyToMany

の関係になります

models.py
import uuid
from django.db import models
from django.core.validators import RegexValidator

# 本
class Book(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(max_length=50)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["title"]
        db_table = "Book"

# 作者
class Author(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    book = models.ForeignKey("Book", on_delete=models.CASCADE)
    name = models.CharField(max_length=50)
    created_at = models.DateTimeField(auto_now_add=True)
    
    class Meta:
        db_table = "Author"

# お客様
class Customer(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    kana = models.CharField(max_length=50)
    name = models.CharField(max_length=50)
    age = models.IntegerField()
    post_no = models.CharField(
        max_length=7, validators=[RegexValidator(r"^[0-9]{7}$", "7桁の数字を入力してください。")]
    )
    book = models.ManyToManyField("Book")
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["name", "age"]
        db_table = "Customer"

fixture用のディレクトリとファイルを用意

fixturesフォルダをアプリケーションディレクトリ配下に作り、fixtures内にデータを作成していきます

└── アプリケーションディレクトリ
    └── fixtures
         └── fixture用ファイル

fixtureは

  • xml
  • yaml
  • json

の3種類のいずれかを使用することができます
今回はjsonを使用しますので下記のようにbook.jsonを用意してみました

└── アプリケーションディレクトリ
    └── fixtures
         └── book.json

fixtureを作成してみよう!

fixtureを作成する時は1Modelにつきデータは2つまであれば十分です
以下のように

  • modelに対応するアプリケーション名とModel
  • PrimaryKey
  • PrimaryKey以外のカラムと対応するデータ
  • 他ModelのPrimaryKeyに対応するForeignKey

を記載していきます

book.json
[
    {
    "model": "<アプリケーション名>.Book",
        "pk":1,
        "fields": {
            "title":"ハリー・ポッターと賢者の石",
            "created_at":"2022-07-28T00:31:09.732Z"
        }
    },
    {
    "model": "<アプリケーション名>.Book",
        "pk":2,
        "fields": {
            "title":"ノルウェーの森",
            "created_at":"2022-07-28T00:31:09.732Z"
        }
    },
    {
    "model": "<アプリケーション名>.Author",
        "pk":1,
        "fields": {
            "book":1,
            "name":"J・K・ローリング",
            "created_at":"2022-07-28T00:31:09.732Z"
        }
    },
    {
    "model": "<アプリケーション名>s.Author",
        "pk":2,
        "fields": {
            "book":2,
            "name":"村上春樹",
            "created_at":"2022-07-28T00:31:09.732Z"
        }
    },
    {
    "model": "<アプリケーション名>.Customer",
        "pk":1,
        "fields": {
            "kana":"タナカイチロウ",
            "name":"田中一郎",
            "age":20,
            "post_no":"6003333",
            "book":[1,2],
            "created_at":"2022-07-28T00:31:09.732Z"
        }
    },
    {
    "model": "r<アプリケーション名>.Customer",
        "pk":2,
        "fields": {
            "kana":"ヤマダハナコ",
            "name":"山田花子",
            "age":20,
            "post_no":"6004444",
            "book":[1,2],
            "created_at":"2022-07-28T00:31:09.732Z"
        }
    }
]

Primarykey及びForeignkey

int型のidおよびuuidは1,2と順番に割り振ることができます

many to many fieldの時

今回の例みたいにCustomerとBookの関係はManyToManyの関係なのでCustomerのModelのbookのfieldにはCustomerのPrimaryKeyを全て記載する必要があります
そのため、

"book":1

と記載すると

'int' object is not iterable: field_value was '1'

というエラーが返ってきてしまうため、例のようにList内にPrimaryKeyを全て記載します

"book":[1,2]

timezone

Djangoだとデフォルトでtimezoneが有効になっているため、
例えば

"created_at":"2022-07-28 00:31:09.732"

という風にdatetime型の表記のまま記載すると

RuntimeWarning: DateTimeField Book.date received a naive datetime while time zone support is active.

という警告が出ます

"created_at":"2022-07-28T00:31:09.732Z"

と記載することでtimezoneに対応するdatetimeをDBに入れることができます

作成したデータをDBに入れてみよう!

loaddataコマンドを実行するとデータを入れることができます
今回はbook.jsonのfixtureを使っていますがbookの箇所は自身がつけたfixtureの名前に置き換えてください

python manage.py loaddata book.json
Installed 6 object(s) from 1 fixture(s)

MySQLのテーブルを確認しましょう

以下のようにデータを入れることができたら成功です

Book
mysql> select * from Book;
+----------------------------------+-----------------------------------------+----------------------------+
| id                               | title                                   | created_at                 |
+----------------------------------+-----------------------------------------+----------------------------+
| 00000000000000000000000000000001 | ハリー・ポッターと賢者の石                           | 2022-07-28 00:31:09.732000 |
| 00000000000000000000000000000002 | ノルウェーの森                                  | 2022-07-28 00:31:09.732000 |
+----------------------------------+-----------------------------------------+----------------------------+
Author
mysql> select * from Author;
+----------------------------------+-------------------------+----------------------------+----------------------------------+
| id                               | name                    | created_at                 | book_id                          |
+----------------------------------+-------------------------+----------------------------+----------------------------------+
| 00000000000000000000000000000001 | JK・ローリング             | 2022-07-28 00:31:09.732000 | 00000000000000000000000000000001 |
| 00000000000000000000000000000002 | 村上春樹                 | 2022-07-28 00:31:09.732000 | 00000000000000000000000000000002 |
+----------------------------------+-------------------------+----------------------------+----------------------------------+
Customer
+----------------------------------+-----------------------+--------------+-----+---------+----------------------------+
| id                               | kana                  | name         | age | post_no | created_at                 |
+----------------------------------+-----------------------+--------------+-----+---------+----------------------------+
| 00000000000000000000000000000001 | タナカイチロウ            | 田中一郎      |  20 | 6003333 | 2022-07-28 00:31:09.732000 |
| 00000000000000000000000000000002 | ヤマダハナコ             | 山田花子      |  20 | 6004444 | 2022-07-28 00:31:09.732000 |
+----------------------------------+-----------------------+--------------+-----+---------+----------------------------+

参考

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?