1
2

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 3 years have passed since last update.

素人基盤エンジニアがDockerでDjangoを触るシリーズ③:Django admin

Last updated at Posted at 2020-05-05

TL;DR

素人基盤エンジニアがDockerでDjangoを触るシリーズ②:モデルの作成の続き。
1から読みたい場合は↓こちら。
素人基盤エンジニアがDockerでDjangoを触るシリーズ①:DockerでDjangoを作る
今回もDjango Girlsのサンプルを作りながらdjangoと戯れる。
前回はモデルを作成したので今回はViewとTemplateと行きたいところだが、先にDjangoモデルを管理するための管理サイト(admin)を学ぶ。
docker-composeで管理サイトのユーザ作成までを実行するには、作成コマンドであるcreatesuperuserをワンライナーで実行できるように、拡張したコマンドを作る必要があるので、それについても記載している。

Django admin

作成したモデルをGUIで管理するために、Djangoはデフォルトでadminというページを持っている。
今回はその有効化と使い方を見ていく。

①admin.pyの編集

admin.py

下記の通り編集する。

blog/admin.py
from django.contrib import admin
from .models import Post

admin.site.register(Post)

一行目は最初から入っているので、それ以外を追記する形。

よくわかる解説

from django.contrib import admin

adminサイトのアプリケーションモジュール。前回は特に触れなかったが、django.contrib.adminは自分で作成したアプリケーションを追記したsettings.py内のINSTALLED_APPSにも、デフォルトで記載されており、最初から利用できるようになっている。

from .models import Post

同じディレクトリに格納されているmodels.pyから、Postモデルを呼び出している。

admin.site.register(Post)

admin.site.register(Model)で、Modelをadminサイトの管理下に加えることができる。

ではいざ、起動しているコンテナでadminサイトをのぞいてみる。
(docker-compose upは前回から起動しっぱなしの人は不要。)

docker-compose up

下記は別ターミナルから実行。前回は、python manage.py migrate blogを実行してblogディレクトリ下のmigrationsのみマイグレーションしたが、今回は引数を与えずに実行することでadminのモデルもマイグレーションする。

docker-compose exec web bash
python manage.py migrate
exit

http://IPADDRESS:8000/adminにアクセス
001.png
ログイン画面が開いた。ここに入るためのログインユーザは、DBのマイグレーションと同じようにmigrate.pyでコマンドを実行して作る必要がある。

②adminサイトのスーパーユーザの作成

docker-compose exec web bash
python manage.py createsuperuser
exit

createsuperuserを実行すると、プロンプトが返ってくる。ユーザ名とメールアドレス、パスワードを入力すると、Superuser created successfully.という出力があるので、ここで入力した情報を先ほどのログイン画面で入力する。

002.png
ログインできた。

③レコードの操作

Postsというところをクリックしてみる。
003.png
POSTモデルは前回定義してテーブルを作成しただけなので、当然 0 postsと表示されている。ADD POSTというボタンでデータの挿入ができそうなので、押してみる。
004.png
前回models.pyで定義した通りに、入力用のテキストボックスやプルダウンリストが並んでいる。ためしに一つ投稿してみる。
005.png
無事データを追加できた。dbのコンテナに入って実際にレコードが入っているか見てみる。

docker-compose exec db bash
psql -U postgres
SELECT * FROM blog_post;
SELECT実行結果
 id | title |        text        |      created_date      |     published_date     | author_id
----+-------+--------------------+------------------------+------------------------+-----------
  1 | TEST  | This is test post. | 2020-05-02 07:47:14+00 | 2020-05-02 07:47:26+00 |         2
(1 row)

ちゃんとレコードが格納されていることを確認できた。レコードの作成、更新、削除も同じ画面で可能。

DB migrateやcreatesuperuser処理を含んだdocker-composeを作成する

これまで、あくまで検証のためということでdocker-compose execを使ってコンテナにログインして処理を行ってきたが、できればここまでをdocker-compose upで一気に構築できるほうがスマートだろう。

①DB migrate

migrateに関してはコマンドを打つのみなので、下記のようにdocker-compose.yamlのcommand:を書き換えることで処理が可能である。(makemigrationはmigrationファイルを作成するだけなので、すでに作成済みのファイルがあれば必要ない。)

docker-compose.yaml
command: sh -c "sleep 5; python manage.py migrate; python manage.py runserver 0.0.0.0:8000"

migrateを実行する前に5秒sleepしているが、たまにPostgresの起動タイミングの問題でエラーが出るため追記している。

②createsuperuser

createsuperuserは実行時に対話的に処理が走るため、これをワンライナーで実行できるようにしないとdocker-composeでは扱えない。
ググると、manage.pyはmanagement/commandsというフォルダを作成してpythonファイルを追加してやれば、コマンドが拡張できるようだ。
https://stackoverflow.com/questions/6244382/how-to-automate-createsuperuser-on-django
https://docs.djangoproject.com/en/1.8/howto/custom-management-commands/
これを使ってユーザ名やパスワードをオプションで受け取ってワンライナーで実行可能なカスタムコマンドを作成する。

cd blog
mkdir -p management/commands
touch management/__init__.py
touch management/commands/__init__.py

createcustomsuperuser.py

management/commands/createcustomsuperuser.py
from django.contrib.auth.management.commands import createsuperuser
from django.core.management import CommandError


class Command(createsuperuser.Command):
    help = 'Crate a superuser, and allow password to be provided'

    def add_arguments(self, parser):
        super().add_arguments(parser)
        parser.add_argument(
            '--password', dest='password', default=None,
            help='Specifies the password for the superuser.',
        )

    def handle(self, *args, **options):
        password = options.get('password')
        username = options.get('username')
        database = options.get('database')

        if password and not username:
            raise CommandError("--username is required if specifying --password")

        super().handle(*args, **options)

        if password:
            user = self.UserModel._default_manager.db_manager(database).get(username=username)
            user.set_password(password)
            user.save()

よくわかる解説

from django.contrib.auth.management.commands import createsuperuser

今回は、createsuperuserのコマンドを拡張するため、importする。

from django.core.management import CommandError

djangoが持っているコマンドエラー。今回は引数が足りないときにエラーを返すために利用。

class Command(createsuperuser.Command):
    help = 'Crate a superuser, and allow password to be provided'

--helpもしくは-hでヘルプを呼び出したときに表示される文言を追加。

    def add_arguments(self, parser):
        super().add_arguments(parser)
        parser.add_argument(
            '--password', dest='password', default=None,
            help='Specifies the password for the superuser.',
        )

コマンドの引数を追加する関数。super().add_arguments(parser)は、元のcreatesuperuserの引数も追加するために実行している。元のcreatesuperuserでは受け付けなかった、passwordという引数を追加。

    def handle(self, *args, **options):
        password = options.get('password')
        username = options.get('username')
        database = options.get('database')

        if password and not username:
            raise CommandError("--username is required if specifying --password")

        super().handle(*args, **options)

        if password:
            user = self.UserModel._default_manager.db_manager(database).get(username=username)
            user.set_password(password)
            user.save()

実際の処理部分。従来のcreatesuperuserの処理により作成されたuserをdbから探してきて、passwordをセットして保存している。

このファイルを作成した上で、docker-compose.yamlを更に下記のように書き換える。

docker-compose.yaml
    command: sh -c "sleep 5; python manage.py migrate; python manage.py createcustomsuperuser --username root --password 123456 --noinput --email 'blank@email.com'; python manage.py runserver 0.0.0.0:8000"

(パスワードは例)
このように、docker-compose.yamlに書けるということは、Kubernetesに移行するときもマニフェスト内でSecretで指定すればよさそうだ。

ここまでの処理が、docker-compose up一行で完了することをぜひ各自確かめてほしい。

docker-compose up

次回は、urls.pyの書き方を学ぶ。(いつになったらViewを書くのか。。)

つづく

1
2
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
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?