Python + Django + SlickGrid で一覧表示

DjangoでのGridライブラリを使用した一覧表示を試してみます。
templateを使用して一覧を表示することもできますが、業務ではGridライブラリを使用するケースも考えておきます。Gridライブラリは、DataSourceにJsonデータを使う場合が多く、今回は、SlickGirdを使用した例ですが、Jquery DataTablesなども同様にして実装できるでしょう。

###1.主な環境

| カテゴリ       |       Right align |
|:-----------------|------------------:|
| os               |windows 10 home 64bit | 
| python           |            3.6.5 |
| django             |              2.0.7|
| SlickGrid|                2.3| 

###2.アプリケーション作成

プロジェクトは作成済であるものとします。作成していない場合は、下記リンクを参考にしてください。
[Python + Djangoのプロジェクト作成](https://qiita.com/t-iguchi/items/f658d607888449cfdf23)

####(1)アプリケーション作成

```cmd.prompt
python manage.py startapp jsontest3
```

####(2)models.py

jsontest3/models.pyを編集します。今回は書籍データとします。

```jsontest3/models.py
from django.db import models

# Create your models here.
class Book(models.Model):
    """書籍"""
    name = models.CharField('書籍名', max_length=255)
    publisher = models.CharField('出版社', max_length=255, blank=True)
    page = models.IntegerField('ページ数', blank=True, default=0)

    def __str__(self):
        return self.name
```
※プロジェクトへのmigrate、データの登録などは割愛します。

####(3)views.py

jsontest3/views.pyを編集します。

```jsontest3/views.py
from django.shortcuts import render
from collections import OrderedDict
from .models import Book
import json

def index(request):
    """JSONテスト"""
    books = []
    for book in Book.objects.all().order_by('id'):
        book_dict = OrderedDict([
            ('id', book.id),
            ('name', book.name),
            ('publisher', book.publisher),
            ('page', book.page),
        ])
        books.append(book_dict)
    jsondata = json.dumps(books, ensure_ascii=False);
    return render(request,
                  'jsontest3/index.html',     # 使用するテンプレート
                  {'form_name': 'jsontest3', 'data': jsondata})         # テンプレートに渡すデータ
```

####(4)urls.py

jsontest3/urls.pyを作成します

```jsontest3/urls.py
from django.urls import path
from . import views

app_name = 'jsontest3'
urlpatterns = [
    path('', views.index, name='index'),   # 一覧
]
```

####(5)jsontest3\templates\jsontest3\index.html

```
{% extends 'commons/base.html' %}

{% load static %}

{% block links %}
<link rel="stylesheet" href="{% static 'SlickGrid/slick.grid.css' %}" type="text/css"/>
<link rel="stylesheet" href="{% static 'SlickGrid/css/smoothness/jquery-ui-1.11.3.custom.css' %}" type="text/css"/>
<link rel="stylesheet" href="{% static 'SlickGrid/examples/examples.css' %}" type="text/css"/>

<style media="screen">
  .slick-header-column.ui-state-default{
    height:26px;
  }
</style>

<script src="{% static 'SlickGrid/lib/jquery-1.11.2.min.js' %}"></script>
<script src="{% static 'SlickGrid/lib/jquery.event.drag-2.3.0.js' %}"></script>
<script src="{% static 'SlickGrid/slick.core.js' %}"></script>
<script src="{% static 'SlickGrid/slick.grid.js' %}"></script>
{% endblock %}

{% block headertitle %}
Json テスト サンプル
{% endblock %}

{% block content %}
<br/>
<div style="width:800px;">
  <div id="myGrid" style="width:100%;height:600px;"></div>
</div>
<script>
  var grid;
  var columns = [
    {id: "id", name: "id", field: "id", width: "20"},
    {id: "name", name: "name", field: "name"},
    {id: "publisher", name: "publisher", field: "publisher"},
    {id: "page", name: "page", field: "page"}
  ];
  var options = {
    enableCellNavigation: true,
    enableColumnReorder: false,
    forceFitColumns: true
  };
  $(function () {
    // point
    var data = {{data|safe}}
    grid = new Slick.Grid("#myGrid", data, columns, options);
  })
</script>
{% endblock %}
```
※SlickGridのライブラリは、staticのフォルダの下にコピーします。

###3.アプリケーションをプロジェクトに追加する

####(1)urls.py

myproject/urls.pyを編集してアプリケーションのルーティングを追加します。

```myproject/urls.py
urlpatterns = [
#・・・
    path('jsontest3/', include('jsontest3.urls')), #"追加")
#・・・
    path('admin/', admin.site.urls),
]
```

####(2)settings.py

プロジェクトにアプリケーションを追加します。

```myproject/settings.py
INSTALLED_APPS = [
#・・・
    'jsontest3', #追加
#・・・
]
```

###4.動作確認
以下のアドレスにアクセスして確認します。
http://localhost:8000/jsontest3/

![image.png](https://qiita-image-store.s3.amazonaws.com/0/246741/a1566895-ce22-8b76-487a-78d8a168104a.png)