DjangoでWebアプリを作ってみる。【vol. 04 モデルを作ってDjangoAdminで操作してみる。】

※[こちら](https://qiita.com/TsJazz27Sumin/items/25b6df3db881ceb42366)の記事の続きです。

### イントロダクション

[Django Girls Tutorial](https://tutorial.djangogirls.org/ja/django_models/)を参考に進めます。
後々、pythonでスクレイピングして、EDINETから有価証券報告書の役員情報を拾ってきてみたいので、対応したモデルを作りたいと思います。

 - 管理担当 / responsible_user
 - 役名 / position
 - 職名 / job
 - 氏名 / name
 - 生年月日 / birthday
 - 略歴 / biography
 - 任期 / term
 - 株式数 / stock
 - 作成日時 / create_date
 - 作成者 / create_user
 - 更新日時 / update_date
 - 更新者 / update_user

モデルの要素として上記で構成しようと思います。

### 新しいアプリケーションの作成

```
python manage.py startapp corporateofficer
```

上記、実行後に以下が作成されています。

<img width="262" alt="corporateOfficer.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280384/c8f0b1e3-e634-e908-b9cf-f07ad184642d.jpeg">

追加したアプリをDjangoに認識させる必要があるので「settings.py」に記述を追加します。

```py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'corporateofficer' # 追加した。
]
```

### モデルの作成

`corporateofficer/models.py`を開いて、以下を記載します。

```python
from django.db import models
from django.utils import timezone

class CorporateOfficer(models.Model):
    # 管理担当
    responsible_user = models.ForeignKey('auth.User', on_delete=models.CASCADE) 
    # 役名
    position = models.CharField(max_length=200)
    # 職名
    job = models.CharField(max_length=200)
    # 氏名
    name = models.CharField(max_length=200)
    # 生年月日
    birthday = models.DateTimeField(
            blank=True, null=True)
    # 略歴
    biography = models.TextField()
    # 任期
    term = models.CharField(max_length=200)
    # 株式数
    stock = models.CharField(max_length=200)
    # 作成日時
    create_date = models.DateTimeField(
            default=timezone.now)
    # 作成者
    create_user = models.CharField(max_length=200)
    # 更新日時
    update_date = models.DateTimeField(
            default=timezone.now)
    # 更新者
    update_user = models.CharField(max_length=200)

    def create(self):
        self.create_date = timezone.now()
        self.update_date = timezone.now()
        self.save()

    def __str__(self):
        return self.name
```

makemigrationsを実行します。

```
python manage.py makemigrations corporateofficer
Migrations for 'corporateofficer':
  corporateofficer\migrations\0001_initial.py
    - Create model CorporateOfficer
```

続いて、migrateを実行します。

```
python manage.py migrate corporateofficer
Operations to perform:
  Apply all migrations: corporateofficer
Running migrations:
  Applying corporateofficer.0001_initial... OK
```

MakemigrationsとMigrateの違いは、[こちら](https://qiita.com/frosty/items/8c715a53d7920c9cd1eb#makemigrations%E3%81%A8migrate%E3%81%AE%E9%81%95%E3%81%84)を確認させていただきました。

`corporateofficer_corporateofficer`でテーブルが作成されていました。
プロジェクト名_モデル名という関係なのですね。。。

これだとさすがにおかしいので、`edinet_corporateofficer`となるように作り直しました。

### DjangoAdminで操作してみる。

Django Girls Tutorialの[ログインページを作ろう（Django admin）](https://tutorial.djangogirls.org/ja/django_admin/)に従って進めていきます。

`admin.py`に以下を記載します。

```py

from django.contrib import admin
from .models import CorporateOfficer

admin.site.register(CorporateOfficer)
```

ログインする前にスーパーユーザーを作っておきます。

```
python manage.py createsuperuser
```
パスワードは、あまりに短いと怒られます。

```
This password is too short. It must contain at least 8 characters.
This password is too common.
```

そのまま作ることも可能なようですが、ここでは`django20190623`としておきました。

アプリケーションを実行します。

```
python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
June 23, 2019 - 12:27:00
Django version 2.2.2, using settings 'firstproject.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
```

http://127.0.0.1:8000/admin/
にアクセスするとログイン画面が表示されるので、先程指定したユーザ名とパスワードでログインします。
すると、モデルに対応したアプリケーションが作成されていることが確認できました。
CRUDの機能が一通り揃っている辺りは、Ruby on Railsと同じような感じですね。

登録したデータを確認すると、PKとしてId（[サロゲートキー](https://qiita.com/tmasu/items/1b8702d8a121cc10aefb)）が振られています。
ここらへんは、JavaのHibernateと同じような思想を感じます。

次は、機能を拡張させていこうと思います。