[Django REST Framework] カスタムユーザーでのプロジェクト構築

## 実行環境
MacOS BigSur -- 11.2.1 
Python3 -- 3.8.2
Django -- 3.1.7
djangorestframework -- 3.12.2

## Django REST Framework(DRF) を始めてみる
これまでDjangoのみを用いたWebアプリケーションの作成をしていましたが、フロントエンドの高度化ができず、DRFを用いてReactと組み合わせてみたい！！！と思いました。Reactに関してはまだ知識が少ないのですが、とりあえずDRFの感覚を掴んでみようと思い、プロジェクト作成をしたのでその手順をメモがてらに記述します。

### DRFとは
ちなみに、DRFとはDjangoでのWebAPIの開発をサポートしてくれるAPIフレームワークです。WebコンソールでAPIの動作確認が可能で、これらによりフロントエンドとバックエンドを切り離してアプリケーション開発を効率的に進められるそうです。

## venvで仮想環境
```
$ python3 -m venv DRFenv
$ . DRFenv/bin/activate
```
上記コマンドでDRF用のvenvを作成し、アクティベイトします。

## 必要なパッケージのインストール
ここからは仮想環境に入ってのコマンドになります。

```
$ pip3 install django
$ pip3 install djangorestframework
```

## プロジェクト・アプリケーションの作成
```
$ django-admin startproject my_api
$ python3 manage.py startapp backend
```
プロジェクト名を「my_api」、アプリケーション名を「backend」としています。

## カスタムユーザーモデルの定義
さて、前回Djangoで開発を進めていたときにカスタムユーザーモデルなるものを途中で知り、ごちゃごちゃコードをいじったのですが途中からうまくユーザーモデルの変更ができなかったという失敗がありました。
Djangoではカスタムユーザーを作成する場合は一番最初のmigrationsのinit(0001)時点でカスタムユーザーを使用することを含めないといけないらしく、よって一番初めにカスタムユーザーモデルの定義を行います！

```my_api/backend/models.py
from django.db import models

# AbstractBaseUserを利用してUserモデルをカスタマイズ
from django.contrib.auth.models import AbstractBaseUser
# PermissionsMixinを用いてUserの認証を行う
from django.contrib.auth.models import PermissionsMixin
# BaseUserManager利用してUserManagerモデルをカスタマイズ
from django.contrib.auth.models import BaseUserManager


class UserProfileManager(BaseUserManager):
    """Manager for user profiles"""

    # ユーザを作成するメソッド
    def create_user(self, email, name, password=None):
        """Create a new user profile"""

        # emailが入力されていないときはValueErrorを呼び出す
        if not email:
            raise ValueError('User must have an email address')

        # emailのドメインを小文字に変換
        email = self.normalize_email(email)
        # UserProfileモデルを参照してuserを定義
        user = self.model(email=email, name=name)
        # userが入力したパスワードをハッシュ化
        user.set_password(password)
        # settings.pyでdefaultに設定されているDBに保存
        user.save(using=self._db)

        return user

    def create_superuser(self, email, name, password):
        """Create and save a new superuser with given details"""

        # 上記create_userを利用
        user = self.create_user(email, name, password)

        # superuserの権限を適用
        user.is_superuser = True
        user.is_staff = True
        user.save(using=self._db)

        return user


class UserProfile(AbstractBaseUser, PermissionsMixin):
    """Database model for users in the system"""

    # カラム名 = データ型（オプション）
    email = models.EmailField(max_length=255, unique=True)
    name = models.CharField(max_length=255)
    # ユーザが退会したらここをFalseにする（論理削除）
    is_active = models.BooleanField(default=True)
    # 管理画面にアクセスできるか
    is_staff = models.BooleanField(default=False)
    # Managerのメソッドを使えるようにする
    objects = UserProfileManager()
    # emailを利用したログイン認証に変更
    USERNAME_FIELD = 'email'
    # 必須項目追加
    REQUIRED_FIELDS = ['name']

    # 1つのnameフィールドで表示したいので、既存のメソッドをオーバーライド
    def get_full_name(self):
        """Retrieve full name of user"""
        return self.name

    def get_short_name(self):
        """Retrieve short name of user"""
        return self.name

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

## settings.pyの変更
```my_api/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework', #追加
    'markdownx', #追加
    'backend', #追加
]

LANGUAGE_CODE = 'ja' #変更

TIME_ZONE = 'Asia/Tokyo' #変更

REST_FRAMEWORK = { #追加
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny',
    ]
}

# Djangoプロジェクトのユーザ認証を変更
AUTH_USER_MODEL = 'backend.UserProfile'

# 画像用
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
```

## 管理画面（admin）に追加
```my_site/backend/admin.py
from django.contrib import admin
from backend import models

admin.site.register(models.UserProfile)
```

## マイグレーションファイルの作成・データベースへの反映
```
$ python3 manage.py makemigrations
$ python3 manage.py migrate
```

## スーパーユーザーの作成
```
$ python3 manage.py createsuperuser
```
このコマンドにより管理ページにログインできるスーパーユーザーの作成をします。
コマンドを実行するとメールアドレス・名前・パスワードの入力を求められますので、自由に設定します。

## サーバーの立ち上げ・起動確認
```
$ python3 manage.py runserver
```
このコマンドによりサーバーを立ち上げます。
http://127.0.0.1:8000/
上記にアクセスし、ロケットの画面が出たら正しく動作しています。

http://127.0.0.1:8000/admin
また、上記で管理ページにアクセスできます。カスタムユーザーでメールアドレスとパスワードでの認証に設定したので、このようにカスタムできていることを確認します。
![スクリーンショット 2021-03-11 19.39.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681173/adb50c14-3368-4e11-17b2-0b2300ac30f6.png)


今回はこれで、開発環境の作成は完了です。
次回から実際に開発を進めていこうと思います。

## 参考
以下のページが非常に分かりやすく、参考にさせていただきました。
- https://pigblog.org/django-restframework-basic4
- https://qiita.com/Piyopanman/items/5ffb9c290d452e0a5782