概要
Djangoのカスタムコマンドの作成方法について解説します
今回は指定したシステムユーザの数分データを生成するカスタムコマンドを作成します
前提
- Djangoのプロジェクトを作成済み
ディレクトリ構成
tree
・
└── application
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── management
│ │ └── commands
│ │ └── seed.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ └── __init__.py
│ └── models.py
└── manage.py
実装
今回は
- models.py
- seed.py
の順に実装していきます
models.py
システムユーザのmodelを作成します
AbstractUserについて詳細に知りたい方は以下の記事を参照してください
from django.contrib.auth.models import AbstractUser, Group
from django.contrib.auth.validators import UnicodeUsernameValidator
from django.core.validators import RegexValidator
from django.db import models
class User(AbstractUser):
"""システムユーザ"""
username_validator = UnicodeUsernameValidator()
# 不要なフィールドはNoneにすることができる
first_name = None
last_name = None
date_joined = None
id = models.AutoField(
primary_key=True,
db_comment="ID",
)
employee_number = models.CharField(
unique=True,
validators=[RegexValidator(r"^[0-9]{8}$")],
max_length=8,
# 管理者のログイン画面で社員番号と表示される
verbose_name="社員番号",
db_comment="社員番号",
)
username = models.CharField(
max_length=150,
unique=True,
validators=[username_validator],
db_comment="ユーザ名",
)
email = models.EmailField(
max_length=254,
unique=True,
db_comment="メールアドレス",
)
created_at = models.DateTimeField(
auto_now_add=True,
db_comment="作成日",
)
updated_at = models.DateTimeField(
auto_now=True,
db_comment="更新日",
)
groups = models.ForeignKey(
Group,
on_delete=models.PROTECT,
related_name="users",
db_comment="社員権限テーブル外部キー",
)
USERNAME_FIELD = "employee_number"
REQUIRED_FIELDS = ["email", "username"]
class Meta:
ordering = ["employee_number"]
db_table = "User"
db_table_comment = "システムユーザ"
def __str__(self):
return self.username
seed.py
指定したシステムユーザの数分データを生成するカスタムコマンドを作成します
Djangoでカスタムコマンドを作成する際はmanagement/commands
配下にPythonファイルを作成します
作成したファイル名がそのままコマンドになります
また、ディレクトリ配下のファイルの先頭に_
を入れるとカスタムコマンドとして認識されなくなります
from django.contrib.auth.models import Group
from django.core.management.base import BaseCommand
from application.models import User
class Command(BaseCommand):
help = "Seeds the database with initial data"
def add_arguments(self, parser):
"""システムユーザの数を指定するオプション
Args:
parser : オプションを追加するためのparser
"""
parser.add_argument(
"--users",
type=int,
help="Specify the amount of users. The default amount of users will be 10",
)
def handle(self, *args, **options):
"""システムユーザを作成するコマンド"""
Group.objects.update_or_create(
id=1,
name="管理者",
)
Group.objects.update_or_create(
id=2,
name="一般",
)
users = options["users"]
if not users:
users = 10
print(f"Creating {users} users")
for id in range(1, users + 1):
try:
user = User.objects.get(id=id)
except User.DoesNotExist:
user = User.objects.create_user(
id=id,
username=f"テストユーザ{id}",
employee_number=str(id).zfill(8),
email=f"example{id}.com",
groups=Group.objects.get(name="管理者"),
)
user.set_password("test")
user.save()
print(f"Created {user}")
print(f"Successfully created {users} users")
一つずつ解説します
add_arguments
今回はコマンドに作成するユーザの数を指定するオプションを付与します
オプション名、型、ヘルパーテキストを指定できます
def add_arguments(self, parser):
"""システムユーザの数を指定するオプション
Args:
parser : オプションを追加するためのparser
"""
parser.add_argument(
"--users",
type=int,
help="Specify the amount of users. The default amount of users will be 10",
)
handle
handle内に実際の処理を記載します
**options内に使用したオプションの値が配列として格納されているのでhandle内で使用できます
今回はオプションを指定しなかったらデフォルトでユーザを10人作成し、オプションを指定したら指定した分だけユーザを作成する処理を記載します
def handle(self, *args, **options):
"""システムユーザを作成するコマンド"""
Group.objects.update_or_create(
id=1,
name="管理者",
)
Group.objects.update_or_create(
id=2,
name="一般",
)
users = options["users"]
if not users:
users = 10
print(f"Creating {users} users")
for id in range(1, users + 1):
try:
user = User.objects.get(id=id)
except User.DoesNotExist:
user = User.objects.create_user(
id=id,
username=f"テストユーザ{id}",
employee_number=str(id).zfill(8),
email=f"example{id}.com",
groups=Group.objects.get(name="管理者"),
)
user.set_password("test")
user.save()
print(f"Created {user}")
print(f"Successfully created {users} users")
コマンドを実行してみよう!
作成したカスタムコマンドのhelpを見てみましょう
python manage.py seed --help
以下のようにコマンドとオプションのヘルパーテキストが表示されていることが確認できました
usage: manage.py seed [-h] [--users USERS] [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color] [--skip-checks]
Seeds the database with initial data
options:
-h, --help show this help message and exit
--users USERS Specify the amount of users. The default amount of users will be 10
--version Show program's version number and exit.
-v {0,1,2,3}, --verbosity {0,1,2,3}
Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output
--settings SETTINGS The Python path to a settings module, e.g. "myproject.settings.main". If this isn't provided, the DJANGO_SETTINGS_MODULE environment variable will be used.
--pythonpath PYTHONPATH
A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".
--traceback Raise on CommandError exceptions.
--no-color Don't colorize the command output.
--force-color Force colorization of the command output.
--skip-checks Skip system checks.
コマンドを実行します
以下のようにログが出力され、システムユーザが作成されたら成功です
python manage.py seed --users 20
Creating 20 users
Created テストユーザ1
Created テストユーザ2
Created テストユーザ3
Created テストユーザ4
Created テストユーザ5
Created テストユーザ6
Created テストユーザ7
Created テストユーザ8
Created テストユーザ9
Created テストユーザ10
Created テストユーザ11
Created テストユーザ12
Created テストユーザ13
Created テストユーザ14
Created テストユーザ15
Created テストユーザ16
Created テストユーザ17
Created テストユーザ18
Created テストユーザ19
Created テストユーザ20
Successfully created 20 users
Userテーブルの中は以下の通りです
django=# SELECT * FROM "User" order by id;
password | last_login | is_superuser | is_staff | is_active | id | employee_number | username | emai
l | created_at | updated_at | groups_id
------------------------------------------------------------------------------------------+------------+--------------+----------+-----------+----+-----------------+----------------+---------
------+-------------------------------+-------------------------------+-----------
pbkdf2_sha256$600000$N70GCTI2t5PvPv1iPh7IgB$n2NVOLXuxvSj29381p9DSvptAPIZSjKzPocQ3VKY2BA= | | f | f | t | 1 | 00000001 | テストユーザ1 | example1
.com | 2024-02-04 10:42:05.67779+00 | 2024-02-04 10:42:06.031773+00 | 1
pbkdf2_sha256$600000$N3fBdPCRjXLOBD2k3toyUt$gkYgtUTqsF6Ck5+AD6IApL83/NvQWFmVJlrxLEkEv/E= | | f | f | t | 2 | 00000002 | テストユーザ2 | example2
.com | 2024-02-04 10:42:06.052773+00 | 2024-02-04 10:42:06.441644+00 | 1
pbkdf2_sha256$600000$a9pkl6ZoaWvyr2xjb6njOQ$581cVCTfw4sVp0w9sbnBe5zMrnaLgIdZ3vE+8TZb+ME= | | f | f | t | 3 | 00000003 | テストユーザ3 | example3
.com | 2024-02-04 10:42:06.451707+00 | 2024-02-04 10:42:06.826803+00 | 1
pbkdf2_sha256$600000$mkfQol0fUYFyYfVLeQfjjX$0oEiSuhOnYPnIHRwhupbwOVMxmFMXsWJwAdmc3Q+qDs= | | f | f | t | 4 | 00000004 | テストユーザ4 | example4
.com | 2024-02-04 10:42:06.835912+00 | 2024-02-04 10:42:07.272309+00 | 1
pbkdf2_sha256$600000$84yicBdzakaQcBKaxXspdJ$0WcDga1WTUZVEQuWlwERoErqIYnBFoqThw9LEhwqr0g= | | f | f | t | 5 | 00000005 | テストユーザ5 | example5
.com | 2024-02-04 10:42:07.279547+00 | 2024-02-04 10:42:07.619245+00 | 1
pbkdf2_sha256$600000$iiUhfF22vlJem5zsq2LQ9W$Jespi8m5ekf7xamLJF5s8e4OKNCjZSalgE6LFpXn4/w= | | f | f | t | 6 | 00000006 | テストユーザ6 | example6
.com | 2024-02-04 10:42:07.628706+00 | 2024-02-04 10:42:07.993764+00 | 1
pbkdf2_sha256$600000$VUNr6RgiBd9kN9SbPMYO1i$dOmYRBHzfo7+F4YTh8drmKb4WKkLPiALymsd/ZzXKlw= | | f | f | t | 7 | 00000007 | テストユーザ7 | example7
.com | 2024-02-04 10:42:08.003249+00 | 2024-02-04 10:42:08.351413+00 | 1
pbkdf2_sha256$600000$rE0Y1GWkpDwWCUbOnhI3OU$YaDCdQVUZCkIxpbsd3bUJWkLyLT7NlNIJF8mBRFzhCk= | | f | f | t | 8 | 00000008 | テストユーザ8 | example8
.com | 2024-02-04 10:42:08.358768+00 | 2024-02-04 10:42:08.688046+00 | 1
pbkdf2_sha256$600000$XeB3OaXr9UPCtNxYkeuGcW$d0Rv3mwnWYeDMniN6t3L6GZWhUs7wvXovNadRpIVSPo= | | f | f | t | 9 | 00000009 | テストユーザ9 | example9
.com | 2024-02-04 10:42:08.696455+00 | 2024-02-04 10:42:09.036743+00 | 1
pbkdf2_sha256$600000$ScENbjJGpqiyi59gd3fhOC$FsDD9cwnJBFkO4ZSn9UqoNmWj041A8tSqQsg3WXBujw= | | f | f | t | 10 | 00000010 | テストユーザ10 | example1
0.com | 2024-02-04 10:42:09.046133+00 | 2024-02-04 10:42:09.486939+00 | 1
pbkdf2_sha256$600000$bILciKYVYW44L9aoQMnDae$4hNdrPVl2wplKIhUiwbOBc88QTQc3zFCkbDvBCUiZ8w= | | f | f | t | 11 | 00000011 | テストユーザ11 | example1
1.com | 2024-02-04 10:42:09.497018+00 | 2024-02-04 10:42:10.017096+00 | 1
pbkdf2_sha256$600000$638VoeGyOVpTIBPXgtDovq$fvzUy9Y/wU89znr1tEdL6oaZ64oty4B1t8lHpok8w3U= | | f | f | t | 12 | 00000012 | テストユーザ12 | example1
2.com | 2024-02-04 10:42:10.027721+00 | 2024-02-04 10:42:10.476937+00 | 1
pbkdf2_sha256$600000$Jcm1530zHbIc5rJAJsZZAX$kDlFDNi5+NJtPWhHnGE76GyRG8xMcIM1GHiUgYnMSoA= | | f | f | t | 13 | 00000013 | テストユーザ13 | example1
3.com | 2024-02-04 10:42:10.485936+00 | 2024-02-04 10:42:10.90018+00 | 1
pbkdf2_sha256$600000$AwTHyMTCCAh5autJc8zbBw$LUmDNCo0AAS/3FvDs9UDD2WIv7wAKShsra4iDhiOjxo= | | f | f | t | 14 | 00000014 | テストユーザ14 | example1
4.com | 2024-02-04 10:42:10.909085+00 | 2024-02-04 10:42:11.293215+00 | 1
pbkdf2_sha256$600000$aUMjLRU5mm5yxWRL9iCMiX$a5CzTJ+2ieR+fGtesWtD/qkgfeXZzoHTaxzaxUld7ZE= | | f | f | t | 15 | 00000015 | テストユーザ15 | example1
5.com | 2024-02-04 10:42:11.302117+00 | 2024-02-04 10:42:11.681076+00 | 1
pbkdf2_sha256$600000$tZMApEQgW92UhSnUYf3qmG$y+DtjW6iWuvZK75B018UJnokGy6mf6JqiMUiA5/yqiQ= | | f | f | t | 16 | 00000016 | テストユーザ16 | example1
6.com | 2024-02-04 10:42:11.690464+00 | 2024-02-04 10:42:12.143705+00 | 1
pbkdf2_sha256$600000$UP2BS5Jy6Ypc8y96A7Ugwc$o1WVEXX78fpPbeMRPEAH/ShVYAKZhJv2saJXl7CeeNQ= | | f | f | t | 17 | 00000017 | テストユーザ17 | example1
7.com | 2024-02-04 10:42:12.153523+00 | 2024-02-04 10:42:12.50654+00 | 1
pbkdf2_sha256$600000$r1KShSqKn6NRV1fV32hNQW$sfdxcC36lC+FwUSklCewsfIEkFy0LjAAJrN47RT7IgI= | | f | f | t | 18 | 00000018 | テストユーザ18 | example1
8.com | 2024-02-04 10:42:12.5147+00 | 2024-02-04 10:42:12.863796+00 | 1
pbkdf2_sha256$600000$XS97oafQ3iujXqWYpKsVWF$JpCrzogirBtDZpRUBEjvYdqiUq7ToydKuz6gICj7Q40= | | f | f | t | 19 | 00000019 | テストユーザ19 | example1
9.com | 2024-02-04 10:42:12.871577+00 | 2024-02-04 10:42:13.228192+00 | 1
pbkdf2_sha256$600000$wUOAM4OuTngr5uSV6UT6GC$hd5tpKPdFFkdNSnhXRwxWJ1MIgj85ms+qBIg2jiWU3I= | | f | f | t | 20 | 00000020 | テストユーザ20 | example2
0.com | 2024-02-04 10:42:13.23653+00 | 2024-02-04 10:42:13.622156+00 | 1
(20 rows)
参考