DjangoでAdminLTE3を扱う

# はじめに

Django で Web アプリケーションを作成する際に、[AdminLTE3](https://adminlte.io/docs/3.0/) という Bootstrap4 をベースにしたテンプレートを用いてダッシュボードを作成する。Bootstrap は HTML／CSS／JavaScript から構成される有名な Web フレームワークで、AdminLTE3 では用意されているクラスを利用するだけで自作の CSS や JS を使用せずに、完成度の高いダッシュボードを作成できる。
実行環境は Windows 10 Pro、WSL2(Ubuntu-20.04)。仮想環境内を作成して実行している。仮想環境の構築方法は、[Djangoチュートリアル①（インストールとプロジェクトの作成）](https://qiita.com/honda28/items/34dceaeeb1cdddb4c9dd)後半を参照。

# django-adminlte-3

django-adminlte-3 というパッケージを使用する。[django-adminlte-3・PyPI](https://pypi.org/project/django-adminlte-3/) にパッケージの説明があった。

> Django AdminLTE3 provides the functionality of the AdminLTE3 theme to developers in the form of standard base templates. Optional styling for Django's built-in admin interface is also provided.

# 準備

[django-adminlte-3](https://pypi.org/project/django-adminlte-3/) にしたがって進める。まず django-adminlte-3 をインストールする。

```
$ pip install django-adminlte-3
```

設定ファイルの INSTALLED_APPS に adminlte3 と adminlte3_theme を追記。読み込み順に影響が受けるようなので、adminlte3、 adminlte3_theme の順で INSTALLED_APPS のはじめに書くのがよさそう。

```python:config/settings.py
INSTALLED_APPS = [
     # General use templates & template tags (should appear first)
    'adminlte3',
     # Optional: Django admin theme (must be before django.contrib.admin)
    'adminlte3_theme',

    ...
]
```

`collectstatic` コマンドを実行する。実行前に STATIC_ROOT の設定もしておくこと。設定の詳細は[Djangoチュートリアル⑦（静的ファイル）](https://qiita.com/honda28/items/bd0bfe8731a17609907c)を参照。

以下コマンドを実行するが、Permission Error が発生。

```
$ python3 manage.py collectstatic

...
PermissionError: [Errno 13] Permission denied: '/var/www'
```

`sudo` をつけて再度実行するも、今度は django がないというエラーが。

```
$ sudo python3 manage.py collectstatic

Traceback (most recent call last):
  File "manage.py", line 11, in main
    from django.core.management import execute_from_command_line
ModuleNotFoundError: No module named 'django'
...
```

原因を調べていると、[virtualenv を使っているときに sudo pythonして動かなくて困惑した私へ](https://qiita.com/suzuki-no-suke/items/83e5c86fea7d06b1eb4d)という記事を発見。参考記事によると、どうも `sudo` を扱う際は仮想環境の管轄外になるようで Django が仮想環境上にインストールされていても sudo 目線ではインストールされていないと認識されるらしい。仮想環境上の python を指定すると実行できた。

```
$ sudo ~/[virtual_env]/bin/python manage.py collectstatic

...
2202 static files copied to '/var/www/apps/static'.
```

以上で、django-adminlte3 の準備ができた。

# 使い方

[base template](https://github.com/d-demirci/django-adminlte3/blob/master/adminlte3/templates/adminlte/base.html) が準備されているので、これを templates ディレクトリ内に base.html として保存する。__このテンプレート自体を編集するのではなく、{% extends "base.html" %} とし、base.html を継承してテンプレートの一部を変更して使う。__

# 具体例

以下で、このテンプレートを表示する例を示す。ここでは dashboard というアプリを想定している。

まず dashboard/urls.py というファイルを作成して、以下コードを書く。

```python:dashboard/urls.py
from django.urls import path

from . import views

app_name = 'dashboard'
urlpatterns = [
    path('', views.MainView.as_view(), name='main'),
]
```

続いて、上記 URLconf を config/urls.py に読み込ませる

```python:config/urls.py
from django.contrib import admin
from django.urls import include, path

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

さらに、dashboard/views.py に以下コードを書く。

```python:dashboard/views.py
from django.shortcuts import render
from django.views.generic import TemplateView

class MainView(TemplateView):
    template_name = 'dashboard/main.html'
```

最後に、templates/dashboard/main.html を作成する。

```templates/dashboard/main.html
{% extends "base.html" %}
```

`$ python manage.py runserver` を実行して、[http://127.0.0.1:8000/dashboard/](http://127.0.0.1:8000/dashboard/) にアクセスすると以下のような画面が表示される。

![dashboard.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769545/ac0ee768-172d-a00b-6b62-f0e2d100c65b.png)

テンプレートの一部を変更するには、templates/dashboard/main.html に以下のようにテンプレートタグの内容を変更すればよい。使用されているテンプレートタグは base.html を参照。

```templates/dashboard/main.html
{% extends "base.html" %}

{% block title %}タイトル{% endblock %}

{% block content %}
your awesome content
{% endblock %}
```

base.html では {% include %} タグで6つの html ファイルを読み込んでいるので、詳細を見たければそれらのファイルの中身を直接眺めるとよい。ファイルの場所は `$ pip show django-adminlte-3` で調べた先の adminlte3/templates/adminlte ディレクトリ以下にある。ベースから見た目を少し変えたいというレベルなら、それらのファイルをコピーして編集するのが一番手っ取り早そう。（コピーした場合は {% include %} での参照をし直すことを忘れずに。）