Djangoでテーブル構成の出力

# はじめに
Djangoのアプリでテーブル構成の図を出力する際につまずいたので備忘録として記事にしました。
業務の中でアノテーションツールとして[Doccano](https://github.com/doccano/doccano)をcloneして使用させていただいているのですが、テーブルの構成がどのようになっているか確認したい場面がありました。
Doccanoの開発環境はDockerで作成されています。

### 使用するライブラリ
ER図の出力にはdjango-extensionの[graph_models](https://django-extensions.readthedocs.io/en/latest/graph_models.html)を使用しました。

# 手順
Doccanoのdocker-compose.ymlはdevelopmentとproductionで分かれています。

```python:docker-compose.dev.yml

version: "3.7"
services:

  backend:
    image: python:3.6
    volumes:
      - .:/src
      - venv:/src/venv
    command: ["/src/app/tools/dev-django.sh", "0.0.0.0:8000"]
    environment:
      ADMIN_USERNAME: "admin"
      ADMIN_PASSWORD: "password"
      ADMIN_EMAIL: "admin@example.com"
      DATABASE_URL: "postgres://doccano:doccano@postgres:5432/doccano?sslmode=disable"
      ALLOW_SIGNUP: "False"
      DEBUG: "True"
    ports:
      - 8000:8000
    depends_on:
      - postgres
    networks:
      - network-backend
      - network-frontend

  frontend:
    image: node:13.7.0
    command: ["/src/frontend/dev-nuxt.sh"]
    volumes:
      - .:/src
      - node_modules:/src/frontend/node_modules
    ports:
      - 3000:3000
    depends_on:
      - backend
    networks:
      - network-frontend

  postgres:
    image: postgres:12.0-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      POSTGRES_USER: "doccano"
      POSTGRES_PASSWORD: "doccano"
      POSTGRES_DB: "doccano"
    networks:
      - network-backend

volumes:
  postgres_data:
  node_modules:
  venv:

networks:
  network-backend:
  network-frontend:

```
ここからライブラリをインストールしていきます。
src/requirements.txtに以下の三行を追加します。

```requirements.txt
graphviz
pydotplus
django-extensions
```
コンテナを立ち上げていきます。

```
docker-compose -f docker-compose.dev.yml up #コンテナの立ち上げ
docker ps #コンテナ名を確認
docker exec -it doccano_backend_1 bash #bashに入る
```
次にコンテナのbashの中で作業していきます。

```
cd src #srcに移動
pip install -r requirements.txt #ライブラリのインストール
apt install graphviz #graphvizのインストール
```

続いてapp/settings.pyのINSTALLED_APPSに`django_extensions`を追加します。

```python:setting.py
INSTALLED_APPS = [
    'whitenoise.runserver_nostatic',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'server.apps.ServerConfig',
    'api.apps.ApiConfig',
    'widget_tweaks',
    'rest_framework',
    'rest_framework.authtoken',
    'django_filters',
    'social_django',
    'polymorphic',
    'webpack_loader',
    'corsheaders',
    'drf_yasg',
    'django_extensions' ←追加
]
```

`docker-compose down`で一度コンテナを落として再度立ち上げます。

```
docker-compose -f docker-compose.dev.yml up --force-recreate
```
再度コンテナのbashに入り、ER図を出力してきます。

```
docker exec -it doccano_backend_1 bash
cd src #srcに移動
source venv/bin/activate #仮想環境に入る
cd src/app #manage.pyがあるディレクトリに移動
python3 manage.py graph_models -a -g -o graph-model.pdf #ER図を出力
```

Doccanoではホストのディレクトリにコンテナのsrc以下がマウントされているのでそのままホストの側からpdfを開くことができます。

## 参考にした記事
- [Django で Models.py の ER図をPDF化](https://qiita.com/ShortArrow/items/3aa68044e7c8d5c029b3)
- [GraphVizのエラー対処（GraphViz’s executables not found）](https://niwakomablog.com/graphviz-error-handling/)