0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

django_datatables_viewで1ページ100件超えが表示できない不具合の対処法

Last updated at Posted at 2024-02-25

Djangoでdatatablesのサーバー連携を使用できるdjango_datatables_viewで、1ページあたり100件を超えるレコードがすべて表示できない不具合の対処法を紹介します。とてもわかりにくい不具合になっており、目視だと気が付かない可能性があります。

※ これは2021/03/28に個人ブログで公開した記事を移植し、CC0-1.0で提供しています。情報は古い可能性があります。

django_datatables_view について

django_datatables_viewとは、datatablesのサーバー連携を使用できるDjangoのクラスベースビューです。
datatablesとは絞り込み・ソートなど多機能なテーブルをかんたんに実装できるjQueryプラグインです。

Djangoの管理画面よりもカスタマイズ豊富な上に、ほとんどプログラムを書くことなく、(デザイン, フロントエンド, バックエンドも)何も考えずにデータベース内容を一覧に表示できます。

django-datatables-viewを使用しているテーブルのスクリーンショット

今回のユースケースでは、次のプログラムをお借りしました。ありがとうございます。

1 ページあたり 100 件超えにするとレコード数がおかしい

datatablesの lengthMenu を変更すると、1ページあたりの表示件数を柔軟に変更できます。

10件でも、1件でも、2^53-1件でも設定できます。

datatables で件数が変更できる部分のスクリーンショット

ある案件で、最大「500件」の選択ができるように設定していました。500件にすると次のようになります。

datatables で表示件数500件にしたスクリーンショット。しかし、1件目から100件目しか表示されていない。

一見すると、正しく表示できていそうに見えますが、皆さん、このスクショにある「不具合」を1点見つけてくださいませ。

いくら北海道がデカいとはいえ、地方自治体が500もあるわけがないのです。(ちなみに179あるらしいです)

試しに次のページに行ってみましょう。

datatables の表示件数500件にして2ページ目に行ったスクリーンショット。501件目から表示される。

群馬県に突入しています。つまり、「1 ~ 500件表示」となっていながら、500件のレコードが表示できていないのです。実際には100件しか表示されていません。

その案件ではデフォルトは100件にしており、テストもそれで通っていたので目視でしか確認しておらず発見できていませんでした。気づきにくい重大な不具合を生んでしまったのです。

django_datatables_view の返却レコード数上限

django_datatables_viewには返却レコード数上限の設定( max_display_length )があります。README.mdには次の記述があります。

set max limit of records returned, this is used to protect our site if someone tries to attack our site
and make it return huge amount of data max_display_length = 500

リクエスト自体は単純なGETのため、やろうと思えば大量のデータを取得する攻撃ができてしまう意図から設定されている設定です。こちらのデフォルト値は 100 になっています。

返却レコード数上限を変更する

正常に動作させるためには返却レコード数上限を変更する必要があります。lengthMenu の最大値を設定しましょう。

from django_datatables_view.base_datatable_view import BaseDatatableView

class ExampleList(BaseDatatableView):
  model = MyModel
  columns = ['id', 'name', 'dateAt', 'updatedAt']
  max_display_length = 500

再度実行してみましょう。

表示件数を500件にしたdatatablesのスクリーンショット。1-500件目が正しく表示されている。

無事群馬県までの500件が表示されるようになりました。

基本設定のクラス化

複数のページで使用している場合、設定漏れがあると不具合の原因となるので、基本設定は基底クラス化してしまいましょう。次のように作ります。

from django_datatables_view.base_datatable_view import BaseDatatableView

class ExtendDatatableView(BaseDatatableView):
  # フロントdatatablesのlengthMenu最大値と揃えること
  max_display_length = 500
from app.library.extend_datatable_view import ExtendDatatableView

class ExampleList(ExtendDatatableView):
  model = MyModel
  columns = ['id', 'name', 'dateAt', 'updatedAt']

まとめ(反省)

  • ライブラリのREADMEはちゃんと読もう
  • 目視で不具合に気がつけるようにテストデータは分かりやすくしよう
  • テストは条件変更した場合の挙動も確認しよう
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?