顧客管理システムのモデル作成

この記事は、「Djangoを使用した顧客管理システムの作成」の2つ目の記事です。
## モデル作成
### 作業内容

https://qiita.com/tomo0227/items/cc893ea4e8e6cfb6ad77

上記の記事で行った要件定義を基に以下の作業を行っていきます。
1. モデルの実装
    * 顧客モデル：``` Customer ```
    * 商談履歴モデル：``` Deal ```
    * カテゴリモデル：``` Category ```
2. リレーション設定
    * 顧客と商談履歴のリレーション(多対1)
    * カテゴリと顧客のリレーション(多対多) 
3. マイグレーション
    * モデルをマイグレーションしてデータベースに適用

### モデルの実装
アプリケーションを作成したときに生成されたcrm_appフォルダの中のmodels.pyを編集することでモデルの実装を行う。
作成されたmodels.pyには最初から``` django.db.models ```がインポートされていて、``` django.db.models ```の中にあるDjangoの基底クラス``` Model ```を使用することで、データベースのテーブルを定義します。
以下が作成したモデルになります。
```:crm_app/models.py
from django.db import models


class Category(models.Model):
    name = models.CharField(max_length=50,verbose_name='カテゴリ名')
    description = models.TextField(verbose_name='カテゴリの説明')
    
    def __str__(self):
        return self.name

class Customer(models.Model):
    name = models.CharField(max_length=100,verbose_name='顧客名')
    email = models.EmailField(verbose_name='メールアドレス')
    phone = models.CharField(max_length=15,verbose_name='電話番号')
    address = models.TextField(verbose_name='住所',blank=True)
    categories = models.ManyToManyField(Category,blank=True)
    created_at = models.DateTimeField(auto_now_add=True,verbose_name='登録日')
    
    def __str__(self):
        return self.name

class Deal(models.Model):
    customer = models.ForeignKey(Customer,on_delete=models.CASCADE)
    title = models.CharField(max_length=200,verbose_name='商談タイトル')
    date = models.DateTimeField(verbose_name='商談日')
    content = models.TextField(verbose_name='商談内容',blank=True)
    responsible_staff = models.CharField(max_length=50,verbose_name='担当者')
    
    def __str__(self):
        return f"{self.title} - {self.date.strftime('%Y-%m-%d')}"  # 日付をフォーマットして返す
```
モデルは``` CharField ```や``` TextField ```のようなフィールドを使用して定義していきます。簡単に使用したフィールドを紹介します。
#### CharField
主に文字列を扱うフィールドです。カテゴリ名や顧客名などのところで使用しています。
このフィールドは文字数制限``` max_length ```の引数設定が必要です。
#### TextField
``` TextField ```は``` CharField ```同様に文字列について扱いますが、文字列といっても文章を扱います。改行できるところが``` CharField ```と異なります。
#### EmailField
主にメールアドレスを扱うフィールドです。メールアドレスで使用される＠の記述がないとエラーを出力します。
#### DateTimeField
日にちと時間を扱うフィールドです。PythonのDate(Datetime)型``` 例：2024-02-07 ```として扱います。引数の``` auto_now_add ```をTrueに設定するとオブジェクトを作成した日時を保持してくれます。
#### ManyToManyField・ForeignKey
どちらもリレーションを行うフィールドです。詳しくは後ほど説明します。

#### def ＿str＿(self):について
＿str＿メソッドはオブジェクトを文字列として表現するときに使われます。モデルで＿str＿を定義すると、管理画面やシェルでオブジェクトを見やすく表示することができます。
### リレーション設定
リレーションとはデータベースのテーブル同士を関連付けることで、Djangoでは簡単に定義することができます。
Djangoでよく使われるリレーションの種類は、以下の3つがあります。
1. OneToOneField(1対1)：1つのモデルのインスタンスが、他のモデルのインスタンスと1対1で対応
2. ForeignKey(多対1)： 複数のレコードが、1つのレコードに紐づく
3. ManyToManyField(多対多)：複数のレコードが、複数のレコードと関係を持つ
ここでは、使用した``` ForeignKey ```と``` ManyToMany ```について説明します。
#### ForeignKey
``` ForeignKey ```は1つのモデルが複数の別のモデルのインスタンスを持つ関係を表します。今回の顧客管理システムでは、1人の顧客に対して、複数の商談履歴を持てるようにフィールドを作成しました。
```
class Customer(models.Model):
    name = models.CharField(max_length=100,verbose_name='顧客名')
    email = models.EmailField(verbose_name='メールアドレス')
    phone = models.CharField(max_length=15,verbose_name='電話番号')
    address = models.TextField(verbose_name='住所',blank=True)
    categories = models.ManyToManyField(Category,blank=True)
    created_at = models.DateTimeField(auto_now_add=True,verbose_name='登録日')


class Deal(models.Model):
    customer = models.ForeignKey(Customer,on_delete=models.CASCADE)
```
引数の``` on_delete ```は内容を削除するときのオプションを設定するもので、今回の場合は、``` Customer ```が削除されたとき、同時に商談履歴``` Deal ```も削除されるというものです。
#### ManyToManyField
``` ManyToManyField ```は複数のレコードが複数のレコードと関係を持つリレーションを表します。今回で言うと1人の顧客に対して様々な種類のカテゴリで登録できるということです。
``` 
class Category(models.Model):
    name = models.CharField(max_length=50,verbose_name='カテゴリ名')
    description = models.TextField(verbose_name='カテゴリの説明')
    
class Customer(models.Model):
    categories = models.ManyToManyField(Category,blank=True)
```
引数の``` blank ```は空欄でも保存できるようにするオプションです。
### マイグレーション
Djangoのマイグレーションとは、モデルの変更をデータベースの構造に反映させる仕組みのことです。例えば、モデルを作成したり、変更したりしたときに、データベースに適用させるため使います。
コンソール画面で以下のコードを実行すると行えます。
```:マイグレーション
python manage.py makemigrations #変更点を検出し、マイグレーションファイルを作成
python manage.py migrate        #データベースに適用
```

今回はこれで以上です。次回Viewの作成を行います。

1つ目：Djangoを使用した顧客管理システムの作成
https://qiita.com/tomo0227/items/cc893ea4e8e6cfb6ad77
2つ目：顧客管理システムのモデル作成
https://qiita.com/tomo0227/items/11f6a262ee1da183fd70
3つ目：顧客管理システムのCRUD機能の実装
https://qiita.com/tomo0227/items/054c974e104f81ea82db
4つ目：商談履歴管理システムの作成
https://qiita.com/tomo0227/items/7b9934ab4bc36cdcd4e8
5つ目：Djangoで検索・ダッシュボード機能を作ってみた。
https://qiita.com/tomo0227/items/a86f7bf038e87be11892