【Django】adminインターフェイス標準のdjango.jQuery(jQuery)を使ってカスタマイズ


投稿日 2019年11月12日 >> 更新日 2023年3月2日

今回はadminサイトの追加・編集ページ内にて、jQueryを使った実装をしていきたいと思います。

Djangoのadminでは標準でjQueryライブラリ(Django2.1からjQuery3.3.1)が備わっており、必要に応じて使うことができます。

jQueryとは、Webブラウザ用の静的ファイルに記述するJava Scriptコードを、短いコードで表現することのできるJava Scriptライブラリです。

通常jQueryを使うには別途ファイルのダウンロードが必要ですが、adminサイトで使う場合は「staticfile」を有効にするだけで使うことができます。

そしてjQueryのファイルが置かれている場所は、Djangoディレクトリ内のソースコードです。

Djangoのファイルが置かれているディレクトリを取得するには、ターミナルにて以下のコマンドを与えます。


$ python3 -c 'import django; print(djgo.__path__)'
['/home/user/仮想環境/lib/python3.6/site-packages/django']
# /django

django
   |--contrib
          |--admin
                 |--static
                      |--admin
                            |--js
                                |--vendor
                                      |--jQuery

jQueryのバージョンアップをしたい場合などは、jQueryディレクトリ内のファイルを置き換えることによって切り替えることができるそうです。

この記事では簡単な説明にとどめているので、詳しく知りたい方はDjango公式ドキュメントをご参照ください。

adminサイトの追加・編集ページのカスタマイズについて別の記事でも説明しているので、宜しければこちらの「【Django】adminサイトの追加・編集ページのレイアウトをカスタマイズする」もご参照ください。

実行環境&使用ライブラリ

実行環境
Windows Subsystem for Linux
Python 3.6.8
pip 9.0.1
使用ライブラリ ライセンス
Django==2.2.6 BSD

モデルの作成

まずは予め作成してあった「item」というアプリディレクトリ内の「models.py」にてモデルを定義します。

# project/item/models.py

from django.db import models


class Item(models.Model):
    item = models.CharField('アイテム', max_length=50)
    quantity = models.IntegerField('数量', default=1)
    unit_price = models.CharField('単価', max_length=20)
    amount_money = models.CharField('金額', max_length=20)

    def __str__(self):
        return self.item

    class Meta:
        verbose_name = 'アイテム'
        verbose_name_plural = 'アイテム'

「admin.py」の初期設定

# project/item/admin.py

from django.contrib import admin
from .models import Item


admin.site.register(Item)

Djangoを起動してadminサイトの追加・編集ページにアクセスすると以下のようになります。

静的ファイルを扱えるように設定する

adminサイト内で静的ファイルを使う為に、「admin.py」を編集します。

特定のモデルをクラス定義し、そのクラス内で「Mediaクラス」を定義します。

# project/item/admin.py

from django.contrib import admin
from .models import Item


class ItemAdmin(admin.ModelAdmin):

    class Media:
        css = {'all': ('admin/css/styles.css',)}


admin.site.register(Item, ItemAdmin)

この「class Media」にそれぞれの静的ファイルの位置を教えることによって、Djangoはstaticディレクトリもしくわmediaディレクトリを読み込みに行きます。

ディクショナリの「all」キーはメディアタイプで他にも数種類あります。(詳しくはDjango公式ドキュメントへ)

Djangoは最初にstaticディレクトリ内のファイルを見に行くので、staticディレクトリ以降のパス「admin/css/styles.css」としています。

それではDjangoがこのstaticファイル内を読み込むよう設定していきます。

プロジェクトディレクトリ内の設定ファイル「settings.py」に以下を追記します。

# project/project/settings.py

.......
.......

""" 追記 """
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),  
)

STATIC_URL = '/static/'

アプリディレクトリ内に「static」ディレクトリを作成し、「admin.py」に記述した通りの配列でstyles.cssを配置します。

# project/item

item
  |--__pycache__
  |--migrations
  |--static
        |--admin
              |--css
                  |--styles.css

※適用されているか確認する場合は、adminサイトの追加・編集ページでリロードを行うとターミナル上に読み込んでいるファイルのログが吐き出されます。

さっそく「styles.css」ファイルに記述していきましょう。

レイアウトを変更したいクラス名やIDを調べるには、ブラウザの「開発者ツールもしくわデベロッパーツール」を使います。

私の場合はGoogle Chromeを使っているので、画面右上のメニューを開き「その他のツール」→「デベロッパーツール」をクリックすることで、現在開かれているページのHTMLを調べることができます。

モデルフィールドのラベルを選択する場合は、上図にもあるようにfieldsetタブ内のlabelを指定します。

/* project/static/admin/css/styles.css */

fieldset label {
    background: gold;
    margin-right: 1%;
}

スタイルシートが適用されない場合はお使いのブラウザで、「履歴・Cookie・キャッシュ」の削除を行うとすぐに反映される場合があります。

単価・金額のフォームサイズを変更します。

/* project/static/admin/css/styles.css */

fieldset label {
    background: gold;
    margin-right: 1%;
}

/* 単価のインプット枠 */
fieldset .field-unit_price input {
    width: 15%;
}

/* 金額のインプット枠 */
fieldset .field-amount_money input {
    width: 15%;
    background: whitesmoke;
}

jQueryを使ってリアルタイム計算

CSSファイルを扱えるようになったことなので、次はJava Scriptファイル読み込むように設定していきたいと思います。

「admin.py」の「Mediaクラス」に追記します。

# project/item/admin.py

from django.contrib import admin
from .models import Item


class ItemAdmin(admin.ModelAdmin):

    class Media:
        css = {'all': ('admin/css/styles.css',)}
        js = ('admin/js/sum.js',)      # 追記


admin.site.register(Item, ItemAdmin)

この記述により、「sum.js」というJava ScriptのファイルをadminサイトのItemモデル内で扱えるようになります。

しかし残念なお知らせがあります。

当Webサイト管理人はJava Scriptにまだまだ乏しいためコード内の記述に関してはやんわりとした説明になります。

なのでこちらを参考にすると理解が深まるかと思います。

気を取り直しまして、「sum.js」内のコードはこちらです。

// project/static/admin/js/sum.js

// 数量と単価を乗算し金額に表示させる
$(function($){
  django.jQuery('fieldset').keyup(function(){
    var numA = $('#id_quantity').val();
    var numB = $('#id_unit_price').val();
    // 整数に置き換えて変数に渡す
    numA = parseInt(numA);
    numB = parseInt(numB);
    // 乗算された数を渡す
    $('#id_amount_money').val(numA*numB);
   });
});

これはDjangoが用意している名前空間のfieldsetタグ内にある各ID名を関数に納めています。

ID名はinputタグ内に指定されているので、デベロッパーツールを使って確認してみましょう。

そして「django.jQuery()」の部分に注意してください。

これはadmin内で使えるDjangoの名前空間です。

本来であれば「$()」や「jQuery()」のように記述しますが差別化をすることによって他のコードとぶつからないといった事があるそうです。

では実際に入力してみましょう。

上手くいったでしょうか?

adminサイトを深掘りしていくと、色々な機能を追加できたり新しく機能を作ったりすることができるのでますます便利に開発を進めることができます。

テンプレートで表現することも大事ですが、adminサイトを制することによってDjangoを制すると言っても過言ではない気がします。

どんどんDjango力を付けていきましょう。

それでは以上となります。

最後までご覧いただきありがとうございました。