Djangoを久しぶりに触る人が基本を思い出すための記事(3/3)～models(db)～

Djangoを久しぶりに触らんといけなくなったけど、基本的なことを忘れてしまった。
そんな方に向けての記事です。（その３）
今回はmodels(db)の記述方法。

[(その１)Djangoを久しぶりに触る人が基本を思い出すための記事(1/3)～ターミナル、urls.py、views.py～]
(https://qiita.com/taole33/items/9f7b0ea79a47648f37dc)
[(その２)Djangoを久しぶりに触る人が基本を思い出すための記事(2/3)～templates（html）～]
(https://qiita.com/taole33/items/dc9fec063cad4ff177aa)

##概要
models.pyではデータベースを扱います。


##全体の流れ
・models.pyの記述(テーブル、リレーションの定義)
　　　　↓
・ターミナルでマイグレーション(model.pyの記述に基づいてデータベースを作成)


##データベースの定義
models.pyに以下のようにテーブルを作成するための記述をします。
models.Modelを継承することで、テーブルを作成できます。

```python:models.py
from django.db import models

class MyTable(models.Model):
 #MyTableは任意の名前。これがテーブル名になる

```


継承したクラスの中に、テーブルのカラムを以下の形で定義します。
以下の例では、models.TextFieldを使用していますが、これはtext型を定義するためのクラスです。
他には、以下のようなクラスがあります。カラムのデータ型に合わせて、選んでください。
・models.CharField()
・models.IntegerField()
・models.DateField()
・models.DateTimeField()
・models.BooleanField()
など


```python
カラム名 = models.TextField()
#カラム名は任意の名前
#クラスTextFieldをインスタンス化
```

models.TextField()などのクラスには、以下のように、引数によってカラムの制約を指定することができます。

```python
カラム名 = models.TextField(blank=True,null=True)
#blankの制約とnullの制約が有効になるため、blank値やnull値が入力できなくなる
```

指定できる引数は、以下のものです。(以下に記載しているNoneやFalseなどの値はデフォルト値)

```
verbose_name=None,
name=None,
primary_key=False,
max_length=None,
unique=False,
blank=False,
null=False,
db_index=False,
rel=None,
default=NOT_PROVIDED,
editable=True,
serialize=True,
unique_for_date=None,
unique_for_month=None,
unique_for_year=None,
choices=None,
help_text='',
db_column=None,
db_tablespace=None,
auto_created=False,
validators=(),
error_messages=None
```


##外部キーの定義(1対多)
以下のように、他のテーブルを参照する側（外部キーを設定する側）に、models.ForeignKey()で参照するテーブルを指定します。
on_delete=の部分で外部キー制約(被参照テーブルの行を削除した時の挙動)を指定します。


```python:models.py
from django.db import models


class MyTable1(models.Model):
    name = models.CharField(max_length=32)

class MyTable2(models.Model):
    mytable1 = models.ForeignKey(MyTable1, null=True, blank=True,
                                 on_delete=models.SET_NULL)
    
```
↓ここの部分です。

```python:models.py
    mytable1 = models.ForeignKey(MyTable1, null=True, blank=True,
                                 on_delete=models.SET_NULL)
    
```

##外部キーの定義(1対1)
models.OneToOneFieldを使用することで、1対1のリレーションを指定します。

```python:models.py
from django.db import models


class MyTable1(models.Model):
    name = models.CharField(max_length=32)

class MyTable2(models.Model):
    mytable1 = models.OneToOneField(MyTable1, null=True, blank=True,
                                 on_delete=models.SET_NULL)
    
```


##外部キーの定義(多対多)
models.ManyToManyFieldを使用することで、多対多のリレーションを指定します。
多対多のリレーションの場合、中間テーブルで双方のテーブルの主キーを関連づけるのが定石です。
そのような面倒な中間テーブルの作成もManyToManyFieldを記述することで、後述のマイグレーションによりDjangoが勝手にやってくれます。

```python:models.py
from django.db import models


class MyTable1(models.Model):
    name = models.CharField(max_length=32)

class MyTable2(models.Model):
    mytable1 = models.ManyToManyField(MyTable1, null=True, blank=True,
                                 on_delete=models.SET_NULL)
    
```

##マイグレーション
マイグレーションを行うことで、models.pyに記述した情報に基づいてdbが構築されます。
以下のコマンドをターミナルに打つことで、マイグレーションファイルを作成することができます。
すでにマイグレーションファイルがある場合は、差分を作成してくれます。

```python:ターミナル
manage.py makemigrations
```

マイグレーションファイルを作成しただけでは、dbは作成されません。
以下のコマンドを入力することで、マイグレーションファイルをもとにdbを作成できます。

```python:ターミナル
manage.py migrate
```


##次回
forms.pyについては次回書きたい