DjangoとMkDocsで簡単ドキュメントサイトを構築する

# はじめに
プロジェクトのドキュメントをマークダウンを使って、フロー図やUML図も書いてさらにホスティングしたいけど、クラウド（github pagesとかgitlab pages）は使えない、でも認証くらいはかけたいって思った時に、Django+MkDocsでそういったものが簡単に作れないかなと思ったのがきっかけです。（実用性があるかは不明ですが）


# MkDocsについて
MkDocsは、プロジェクトドキュメントをマークダウン形式で書ける高機能な静的サイト生成プログラムです。Pythonで作成されていてpipでインストールします。テーマも用意されていて、ReadtheDoc風にもできます。

# 前提
今回は、Django2系で構築します。

# 作成
### Djangoプロジェクトを作成
```console
# プロジェクトを作成
django-admin startproject django_mkdocs

# docsアプリケーションを作成
python manage.py startapp docs

# MkDocsをビルドしたHTML等の静的ファイルを格納するディレクトリを作成
mkdir docs/static
```

作成したdocsアプリケーションをsetting.pyに登録します。

```python
･･･
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'docs',
]
･･･
```


### MkDocsのインストール
MkDocsは以下のコマンドを入力することで、プロジェクトを
新規作成できます

```console
# 例
mkdocs new (プロジェクト名)
```
今回は、mkdocsというプロジェクトを作成しようと思うので

```console
mkdocs new mkdocs
```
と、Djangoプロジェクト上で入力します。
すると、以下のようなファイルが生成されていると思います。

```
mkdocs
├docs
│  └index.md :　プロジェクトドキュメント
└ mkdocs.yml　　:　configファイル
```
次に、MkDocsがきちんと動作するか確認するために
ドキュメントサーバーを起動します。

```console
cd mkdocs
mkdocs serve

・・・
[I 180929 22:49:17 server:292] Serving on http://127.0.0.1:8000
[I 180929 22:49:17 handlers:59] Start watching changes
[I 180929 22:49:17 handlers:61] Start detecting changes
[I 180929 22:49:21 handlers:132] Browser Connected: http://127.0.0.1:8000/
```
と表示されて、ローカル上で問題なくMkDocsが起動しました。

特にこのままでも問題ないのですが、yml直下でコマンドを打たないと
いけないため、ymlの場所と、ドキュメント(index.md)の場所を変えます。

```
mv mkdocs/mkdocs.yml .
mv mkdocs/docs/index.md mkdocs/
rm -r mkdocs/docs
```
このままだと、MkDocsが動作しないためmkdocs.ymlを書き換えます。

| key | 内容| 
| :---- | :--- | 
| site_name | サイト名 |
| theme | テーマ |
| docs_dir | マークダウンファイルを格納するディレクトリ |
| site_dir | ビルドされたHTMLファイル等を格納するディレクトリ | 

今回は以下のように設定します。

```yml
site_name: Django + MkDocs Site

docs_dir: 'mkdocs'
site_dir: 'docs/static/docs'
```
この後で、以下のコマンドを入力し、MkDocsをビルドしてみます。

```console
mkdocs build
```
docs/static/docs以下にビルドファイルが作成されれば大丈夫です。　

MkDocsのコマンドやymlについては、公式サイトを参照ください。
https://www.mkdocs.org

## Docsアプリケーションを作成
### django_mkdocs

```python
"""
django_mkdocs/urls.py
"""

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('docs/', include('docs.urls')),
]

```
docsアプリケーションへincludeを追加します。
（アプリケーション毎にurls.pyを定義する方がいいというベストプラクティスに習って）

```python
"""
settings.py
"""
･･･
TIME_ZONE = 'Asia/Tokyo'
･･･
# MkDocsのディレクトリ
DOCS_DIR = os.path.join(BASE_DIR, 'docs/static/docs')
DOCS_STATIC_NAMESPACE = os.path.basename(DOCS_DIR)
```
settings.pyについてタイムゾーンを変更し、
MkDocsディレクトリのstatic_namespaceを定義します。
※ LANGUAGE_CODEは特に変更してません。

## 認証アプリケーションを追加
### accountsアプリケーションを作成
```console
python manage.py startapp accounts
```

### 認証を追加

#### Djangoの認証機能を使用
Djangoには標準でログイン・ログアウト機能がありますので、それを使いたいと思います。

#### カスタムUserモデルを作成
Djangoには標準で認証機能があり、Userモデルを持っているのですが、
そのまま使用すると、後から変えようと思うと大変（らしい）なので、
そのまま継承したカスタムしてないカスタムUserモデルを定義します。

authのUserモデルをそのままコピーして、

```python

･･･
class User(AbstractBaseUser, PermissionsMixin):
･･･
　　　　　　　　# is_mkdocsを追加（TrueのユーザだけMkDocsを表示させる）
    is_mkdocs = models.BooleanField(
        _('MkDocs User'),
        default=False,
        help_text=_('the user can use MkDocs site.'),
    )

    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')
        # 抽象モデル設定をコメント化
        # abstract=True
･･･
```

というモデルを追加して、

Setting.pyに、認証用モデルを

```python
AUTH_USER_MODEL = 'accounts.User'
```
を追加します。
その後で、

```console
django manage.py makemigrations
django manage.py migrate
```
でマイグレーションすると、、カスタムユーザテーブルが作成されます。

### ログイン、ログアウト画面を作成する
単純にログインやログアウトをさせるためには、urls.pyのURLパターンに

```python
path('accounts/', include('django.contrib.auth.urls')), 
```
を追加すれば良いですが、自分でカスタマイズする場合は

```python
path('accounts/', include('accounts.urls')),
path('accounts/', include('django.contrib.auth.urls')), 
```
として、accountsのurls.pyやviews.pyなどを追加すれば良いです。
あと以下の設定をSettings.pyに追記しておきます。

```python
LOGIN_URL = '/accounts/login'
LOGIN_REDIRECT_URL = '/docs/'
LOGOUT_REDIRECT_URL = '/accounts/login/'
```

その後で、http://127.0.0.1:8000/docs/
にアクセスすれば、ログインとログアウト機能付きのMkDocsの完成です。

ソースコードは以下に置いています。
https://github.com/Taka710/mkdocs_django

# 参考
以下のサイトを参考にさせていただきました。
https://www.hacksoft.io/blog/integrating-a-password-protected-mkdocs-in-django/
https://qiita.com/NAKKA-K/items/7627b6a22f364941b989
https://it-engineer-lab.com/archives/544