Djangoを使って将棋棋譜管理アプリを作る3　～Djangoデフォルトの管理サイトの設定～

## はじめに
Djangoを使って将棋の棋譜管理アプリを作っていくなかでの備忘録、**第3回**です。

## 作業環境
今回の作業環境は以下の通りです

- Windows 10 Pro
- Anaconda
    - version1.7.2
    - python 3.7
        - django 2.2.5
- git
    - version 2.25.0.windows.1
- mysql
    - ver 8.0.15 for Win64 on x86_64

また、Djangoのディレクトリ構造は次のようになります。

```
- kifu_app_project/
    - kifu_app_project/
        - __init__.py
        - setting.py
        - urls.py
        - wsgi.py
    - kifu_app/
        - migrations/
        - __init__.py
        - admin.py
        - apps.py
        - models.py
        - tests.py
        - views.py
    - manage.py
    - .gitignore
```

## 本稿の内容
- Djangoデフォルトの管理サイトの設定

## Djangoデフォルトの管理サイトの設定
Djangoには、DBのデータを閲覧・管理するための管理サイトが、標準で備わっています。
今回はこの管理サイトを使うための設定を行っていきます。

### admin.pyの編集
kifu_appの中にあるadmin.pyを編集します。

```python:admin.py
from django.contrib import admin

# Register your models here.

# 以下追加

from .models import LargeClass, MiddleClass, SmallClass, Information, Kifu

admin.site.register(LargeClass)
admin.site.register(MiddleClass)
admin.site.register(SmallClass)
admin.site.register(Information)
admin.site.register(Kifu)
```

前回作成した、models.pyに作成したクラスを全てimportします。
そして、importしたクラスを全て`admin.site.register()`の引数に渡します。

### ログインのためのユーザー作成
次に、manege.pyが見えるところまで、移動し、以下のコマンドを打ちます。

```
$ python manage.py createsuperuser
Username: <ユーザー名>
Email address: <Eメール>
Password: <パスワード>
```

設定に必要な情報を入力します。
Eメールは入力しなくても大丈夫です。

### ローカルサーバーを立ち上げる
連載もようやく３回目ですが、ようやくサーバーを立ち上げます。
`manage.py`が見えるディレクトリで、次のコマンドを打ってください

```
$ python manage.py runserver
```

`Starting development server at ~`に書いてあるアドレスにアクセスしてみてください。通常はlocalhost:8000のはずです。
下の写真のような画面が表れれば、OKです！
<img width="650" alt="main.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398963/8d9462db-26f3-9462-376c-4536965b46ac.png">


### 管理サイトにログイン
次に今のURLから、`/admin/`にアクセスしてください。(通常はlocalhost:8000/admin/)
そこで、先程設定したユーザー名とパスワードを入力して、ログインします。

恐らく、下の写真のような画面に遷移すると思います。
<img width="474" alt="admin.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398963/894973c3-88f3-4138-e79c-1cb617c6e221.png">


## 管理サイトをカスタマイズ
管理サイトはCSSなどを変更して、自分オリジナルのものに変更できるようです。

ここでは、より使いやすい設定にしていきます。

### 新規データの挿入
まずはデータをいくつか入れてみて下さい。
addボタンを押せば、簡単に挿入できます。

### データ内容を返すように、models.pyを変更
しかし、挿入したデータを一覧から見てみると、*Object*であることしか分からず、いちいち詳細を確認しなくてはいけません。
<img width="478" alt="largeClass.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398963/8e81173c-af98-7a82-9f7b-5624f291baa7.png">

そこで、models.pyの各クラスに、`__str__`メソッドを追加します。

```python:models.py
from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator

# Create your models here.

class LargeClass(models.Model):
    name = models.CharField(max_length=10)

    def __str__(self):      # 追加
        return self.name

class MiddleClass(models.Model):
    large_class = models.ForeignKey(LargeClass, on_delete=models.CASCADE)
    name = models.CharField(max_length=10)

    def __str__(self):     # 追加
        return self.name

class SmallClass(models.Model):
    middle_class = models.ForeignKey(MiddleClass, on_delete=models.CASCADE)
    name = models.CharField(max_length=10)

    def __str__(self):     # 追加
        return self.name

class Information(models.Model):
    date = models.DateTimeField()
    sente = models.CharField(max_length=50)
    gote = models.CharField(max_length=50)
    result = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(3)])
    my_result = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(3)])
    small_class = models.ForeignKey(SmallClass, on_delete=models.CASCADE)
    create_at = models.DateTimeField(auto_now_add=True)
    update_at = models.DateTimeField(auto_now=True)

    def __str__(self):     # 追加
        # return self.date     <- self.dateはdatetime型なので、これではエラー
        return self.date.strftime("%Y/%m/%d_%H:%M:%S")    # このようにstr型に直してreturnする

class Kifu(models.Model):
    information = models.ForeignKey(Information, on_delete=models.CASCADE)
    number = models.IntegerField(validators=[MinValueValidator(0)])
    te = models.CharField(max_length=20)

    def __str__(self):     # 追加
        return self.te
```

`__str__()メソッド`で、表示させたいカラムの変数をreturnさせるようにします。
これでブラウザを更新すると、無事情報が表示されるようになりました。
<img width="476" alt="largeClass2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398963/cb5cd378-2194-0f3e-3b1e-78c306d26851.png">



他にも様々にカスタマイズできるので、以下のサイトを参考にしてみてください。
[Python Django チュートリアル(2)](https://qiita.com/maisuto/items/357d13027e4fe5e10618)
[はじめての Django アプリ作成、その 7](https://docs.djangoproject.com/ja/3.0/intro/tutorial07/)

## 管理ユーザーのパスワードを忘れた場合(2020/03/09 追記)
久しぶりにadmin機能を使おうと思ったら、パスワードを忘れてしまったので、変更方法を調べました。

コマンドプロンプトで以下のコマンドを打って、変更します。

```
$ python manage.py changepassword <変更したいユーザー名>
Changing password for user <>
Password:
Password(again):
Password changed successfully for user <>
```

これでパスワードが変更されます。

また、ユーザー名が分からなくなった場合は、DB(自分の場合はmysql)にログインし、このプロジェクトで使っているDBのうち、auth_userテーブルを確認すればわかります。
(パスワードはハッシュ化されているため、わかりません。)

以下が参考サイトです。
[How to reset Django admin password?](https://stackoverflow.com/questions/6358030/how-to-reset-django-admin-password)


## 次回予告
[Viewの作成][1]


[1]:https://qiita.com/r-programming/items/1c37615346f92ad5fdec