データがたまっても平気な高機能な一覧をData Tables&Djangoで開発(Ajax利用)
概要
一覧の検索やソート、ページングなどを自分で実装するのはなかなかに骨が折れます。いくつかの便利なライブラリがあり、そのひとつであるData TablesをDjangoで使う実装例を紹介します。
ただ、そのまま実装するとデータ量が多くなったときにJavascript側での動作が重くなってしまいます。なので、本記事ではajaxを使ってデータ量が多くなっても対応できるように実装しました。
この記事は、Data Tablesでどのようなことができるのかを詳しく解説するものではなく、まずは動くものができるところまでを体感してもらうことを優先しています。
完成系のイメージはこのような感じです。
完成系のソースはこちらに置いてあります。 github.com tag:v1.0
イチから作る場合の手順
前半はほぼほぼDjangoの話になってしまいます。
DjangoとData Tables関連ライブラリのインストール
まずはDjangoとData Tablesを利用するためのライブラリをインストールします。
$ pip install django==2.2 $ pip install django-datatables-view==1.19.1
※バージョンは多少変わっても動くと思います
Djangoの初期設定&アプリ作成
次にアプリケーションを作ります。
$ django-admin startproject config . $ django-admin startapp sample
このままだとsampleが動いてくれないので、 settings.py
のINSTALLED_APPSにsampleを追加します。
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'sample' # ←これを追記 ]
データベース作成
お次は一覧に表示するためのDBを格納するために、簡単なModelを作るために models.py
を変更します。
from django.db import models # Create your models here. class Book(models.Model): """本""" class Meta: db_table = 'book' title = models.CharField(verbose_name="本のタイトル", max_length=255) author = models.CharField(verbose_name="著者", max_length=255)
本のタイトルと著者名を登録するためだけの簡単なテーブルです。
models.py
ができあがったところで、マイグレートします。今回はData Tablesを試してみることが目的なので、DBはSQLiteとします。(DjangoはデフォルトでSQLiteが指定されるので、特に気にすることはないです)
$ python manage.py makemigrations $ python manage.py migrate
ついでにテスト用のデータも投入します。
$ python manage.py shell < sample/create_testdata.py
URLディスパッチャ作成
まずは、 config/urls.py
にsampleへのディスパッチ行を追加します。
urlpatterns = [ path('admin/', admin.site.urls), path('sample/', include('sample.urls')) # ←ここを追加 ]
続いてアプリの配下にurls.pyを作成します。
from django.urls import path from . import views app_name = 'sample' urlpatterns = [ path('booklist/', views.BookList.as_view(), name='booklist'), path('booklist_ajax/', views.BookJsonView.as_view(), name='booklist_ajax'), ]
ここで、Data Tablesで呼び出すDjango側のエンドポイントを指定しておきます。今回の例では booklist_ajax
としました。
ビューの作成
ビューを作ります。 django-datatables-view
を利用しているので、ajaxのエンドポイント部分はとてもシンプルにできています。
from django.views import generic from django.views.generic import ListView from django_datatables_view.base_datatable_view import BaseDatatableView from .models import Book class BookList(ListView): model = Book template_name = 'sample/book_list.html' class BookJsonView(BaseDatatableView): # モデルの指定 model = Book # 表示するフィールドの指定 columns = ['id', 'title', 'author'] # 検索方法の指定:部分一致 def get_filter_method(self): return super().FILTER_ICONTAINS
BookList
は一覧全体を表示するためのもので、特段捻りもなくクラスビューで構築しました(これはListViewじゃなくても良かった気がします)。
BookJsonView
がData Tables用になります。対象のテーブルを、 model
で指定し、その中から一覧で表示したい項目を columns
で指定します。
FILTER_ICONTAINS
はマストではないのですが、部分一致で検索するために追加しています。
やっと見た目のところに到達・・・
色々とbase.htmlを作ったりとしているのですが、肝となる記述は、 template/sample/book_list.html
の以下の箇所です。
<div class="container"> <table id="datatable" class="table table-striped table-bordered table-hover dataTable no-footer dtr-inline"> <thead> <tr> <th>No.</th> <th>本名</th> <th>著者名</th> </tr> </thead> </table> </div>
ここは、Data TablesのJavascriptでテーブルを完成させるための箇所です。ヘッダーだけ書いておきます。ここで注意しなくてはいけないのが、<th></th>
の数が、views.pyのcolumnsで選択した数と一致することです。
あとは、ajax部分を以下のように書けば勝手にajax向けのエンドポイントにリクエストを投げて、返却されたjsonをいい感じにJavascriptで処理してくれます。
(ほんと便利)
<script> $(document).ready(function() { var oTable = $('#datatable').dataTable({ // ... "processing": true, "serverSide": true, "ajax": "{% url 'sample:booklist_ajax' %}" // 上で作成したエンドポイント }); // ... }); </script>
地味なノウハウとして、今回Bootstrap4を使っているのですが、Bootstrap4のオフィシャルページで指定されるjQueryは「slim」というバージョンで、これだとajaxが動かないです。ですので、 base.html
の以下のところをslimじゃないものに置き換えています。
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
さてやっと動かす日がきた・・・
ここまででおそらく動くようになったはずなので、
$ python manage.py runserver
として、エラーが出ないことを確認したら、 http://127.0.0.1:8000/sample/booklist/
にアクセスしてみてください。
冒頭に張り付けたキャプチャのような画面が表示されるはずです。
さいごに
これだけ高機能のものを自作で作ろうとするととても大変です。数日前に、ページングの実装をしようとして萎えていたので、試してみて実際に動いたときは感動しました。 見た目など融通が効かないところがありそうだなとは思うので、そこはもう少し調べていきたいと思います。
参考
- [Django] 常時Ajaxで動く検索画面を1時間で作ろう! jQuery Datatables サーバ連携機能の紹介 【サンプルアプリ有り】 - Qiita
- DataTables(+Django)でAjax通信 - JoTech
おまけ
Templateの書き方や、startproject時のプロジェクト名などは、以下の書籍を参考にさせていただきました。とても勉強になる良書過ぎてDjango初心者の身分としては大変助かる書籍です。 www.amazon.co.jp