djangoを使ったAPI開発を理解する[part1 目的の整理と環境構築]

諸事情でDjango-rest-frameworkを使えるようになることになったため、その過程を残していきます。

タイトルに`目的の整理と環境構築`としていますが、先に環境構築の内容を書きます。
目的の整理は気になったらこの記事の後半部分の前提項を見てください。

## 環境構築
### 作業する環境
今回の記事を書くにあたり使用した環境はこちら
```
okapi@MBP01 ~ % sw_vers
ProductName:	macOS
ProductVersion:	12.3.1
BuildVersion:	21E258

okapi$ docker --version
Docker version 20.10.5, build 55c4c88

okapi$ docker-compose --version
docker-compose version 1.28.5, build c4eb3a1f
```
今回は`docker-compose`を利用して端末上のpythonは利用しない方針で進めます。
### 元にするdocker-compose.ymlの作成
まずはdocker-compose.ymlを作成します。
(今回はsqlite3を使用するので管理するコンテナは1つだけですが、dbコンテナを将来的に追加する想定です)
```yml:docker-compose.yml
version: '3'

services:
  web:
    build: ./web
    volumes:
      - ./web/code:/code
    ports:
      - "8000:8000"
    tty: true
```
これに合わせてdockerfileを書きます。
```dockerfile:./web/dockerfile
FROM python:3
RUN mkdir /code
WORKDIR /code
```
これで出来上がるのはpython3系のコンテナが1個だけです。
djangoのオフィシャルイメージもあるのですが、最終更新が5年前なのでこれは使わず作ります。

### django関係の準備
ここからはdjangoのチュートリアルも参考にしながら進めていきます。
まず、準備したコンテナをbuild、upしていきます。
起動したコンテナの中でこの先は操作していきます。
```zsh
okapi$ docker-compose build
-中略-
okapi$ docker-compose up -d
okapi$ docker-compose exec web bash
```
まずはインストールから
[djangoオフィシャル](https://docs.djangoproject.com/ja/3.2/topics/install/#installing-official-release)と[django-rest-frameworkオフィシャル](https://www.django-rest-framework.org/#installation)で紹介されている手順でインストール、動作をまずは確認します。
```terminal
root@a4f1172d6665:/code# pip install django
root@a4f1172d6665:/code# python
>>> import django
>>> print(django.get_version())
4.0
root@a4f1172d6665:/code# pip install djangorestframework
root@a4f1172d6665:/code# pip install django-filter
```
と、やるとインストールはできるのですが、このままだとコンテナを立て直したりするとまっさらな状態になってしまいます。
それを防ぐためにpipでは`requirements.txt`に対象を記載しておくことができます。
その対応をします。
```text:./web/reqirements.txt
django
djangorestframework
django-filter
```
作った`requirements.txt`を読み込みます。
これに合わせてdockerfileを書きます。
```diff_docker:./web/dockerfile
FROM python:3
RUN mkdir /code
WORKDIR /code
+ COPY ./requirements.txt /code/
+ RUN pip install -r requirements.txt
```
この状態で再度ビルドしてみます。
```terminal
okapi$ docker-compose down
okapi$ docker-compose up -d --build
okapi$ docker-compose exec web bash
root@a4f1172d6665:/code# pip list
Package             Version
------------------- -------
asgiref             3.5.1
Django              4.0.4
django-filter       21.1
djangorestframework 3.13.1
pip                 22.0.4
pytz                2022.1
setuptools          58.1.0
sqlparse            0.4.2
wheel               0.37.1
```
これで環境は整いました。
ここで終わってもいいのですが、djangoのプロジェクトを立ち上げて、`WORKDIR`の変更までしてあげましょう。

### プロジェクトの立ち上げ

djangoにはプロジェクトとアプリケーションの概念があります。
> プロジェクトとアプリケーション
>> What's the difference between a project and an app? An app is a web application that does something -- e.g., a blog system, a database of public records or a small poll app. A project is a collection of configuration and apps for a particular website. A project can contain multiple apps. An app can be in multiple projects.

[はじめての Django アプリ作成、その 1より](https://docs.djangoproject.com/ja/4.0/intro/tutorial01/#creating-the-polls-app)

ここだけ訳されてなかったので意訳(英弱の理解です、ツッコミは受け付けます)
>>プロジェクトとアプリケーションの間の違いはなんでしょうか？アプリケーションはブログシステムや公的な記録のデータベース、小さな投票アプリのような何かしらを行うwebアプリケーションのことです。プロジェクトは定義のまとまりや、特定のwebサイトに向けたアプリケーションの集合です。一つのプロジェクトは複数のアプリケーションを持つことができます。アプリケーションは複数のプロジェクトに含まれることができます。

今回は環境構築の追加としてやるので、プロジェクトを1つ作ります。
その時は以下のようなコマンドを流します。

```terminal
root@a4f1172d6665:/code# django-admin startproject <プロジェクト名>
```

今回はプロジェクトとして、テキストでのblogサービスのようなアプリケーションを実装します。
そのため、プロジェクト名は`myblog`としてコマンドを実行します。

```terminal
root@a4f1172d6665:/code# django-admin startproject myblog
```

これを実行すると、`myblog`ディレクトリ配下に必要なファイルが自動生成されます。
この生成されたところに、`dockerfile`の`WORKDIR`を設定してこの先の開発を楽にします。

```diff_docker:web/dockerfile
FROM python:3
RUN mkdir /code
WORKDIR /code
COPY ./requirements.txt /code/
RUN pip install -r requirements.txt
+ WORKDIR /code/myblog
```
今回は、パッケージ導入を行う都合で`WORKDIR`設定を2度を行います。
これでビルドし直してみます。

```terminal
okapi$ docker-compose down
okapi$ docker-compose up -d --build
okapi$ docker-compose exec web bash
root@6f4ae531bd2c:/code/myblog# 
```

これで、生成されたディレクトリに直接移動できるようになりました。
ここまでで、環境設定は完了ですが一点注意事項が。
生成したプログラムにはシークレットキーがあります。

```python:./web/code/myblog/myblog/local_settings.py

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = ''
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

```
ここをコミット、プッシュすると音速で監視botからメールがきます。(きました）
なので、別管理する様にしましょう。
今回は`local_settigns.py`を作ってそこに置いておく様にしました。
[【Django】SECRET_KEYなどの機密情報を別ファイルで管理](https://chigusa-web.com/blog/django-secret/)を参考に対応しました。
これで環境準備は完了です。

ここまでのソースはこちら

[django-api-sample(v0.0.2、今回記事の範囲)](https://github.com/poolbooyer/django-api-sample/releases/tag/v0.0.2)
[django-api-sampleリポジトリ](https://github.com/poolbooyer/django-api-sample)

## 次のやること

次はアプリを作成して、createの機能を持たせるところまでを目指そうかなと思っています。
次回はこちら
[djangoを利用したAPIを理解する[part2 アプリを作ってモデル周りの整備]](https://qiita.com/poolbooyer/items/e2782ebbaf7e601c1746)
## 参考

- [Django official image(docker hub)](https://hub.docker.com/_/django)
- [RESTful APIとはなんなのか](https://qiita.com/NagaokaKenichi/items/0647c30ef596cedf4bf2)
- [Django チュートリアル](https://docs.djangoproject.com/ja/4.0/intro/tutorial01/#creating-the-polls-app)
- [【Django】SECRET_KEYなどの機密情報を別ファイルで管理](https://chigusa-web.com/blog/django-secret/)

## 前提

まず自分の現状とどこまでできるようになりたいかからです。

### 現状

- python
  - 2系を使ってちょっとした開発はしたことがある
- django
  - 名前は知ってる、使ったことはない
- django-rest-framework
  - djangoと同じく使ったことない
- その他
  - 他のフレームワーク(ruby on rails/nest.js)や言語(go)の経験は多少ある

### 目指すところ

- APIの一連の実装を進められるようになる
  - CRUDいずれかの機能を持つAPI機能の実装**テストコード**の作成までを一連とする
- DB繋いで使えるようにする
  - 今回の記事の中では一旦DBはsqlite3で一連を身につけつつ、最終的にmysqlのDBと繋いでいく
こんなところを目指すための技術習得を進めます。