LoginSignup
0
0

More than 5 years have passed since last update.

Djangoカスタムフィルタでクエリ実行結果を受け取ってみた

Last updated at Posted at 2017-12-23

やりたいこと

Djangoテンプレート機能のカスタムフィルタで任意のクエリを発行し、その実行結果をテンプレートで表示すること

前提条件

  • Django 2.0
  • python 3.6

アプリ構成

manage.py
polls/
    __init__.py
    models.py
    templatetags/
        __init__.py
        poll_extras.py
templates/
    index.html

実現方法

manage.py
#!/usr/bin/env python
import os
import django
from django.shortcuts import render_to_response

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sample.settings")
    django.setup()

    # テンプレートに渡すキーを取得
    from polls.models import Child
    childs = Child.objects.raw('SELECT id, name FROM child where id = 1')
    child = childs[0]

    # テンプレートを発行
    app_data = {'child': child}
    print(render_to_response(template_name='/sample/templates/index.html', context=app_data))
polls/model.py
from django.db import models

class Child(models.Model):
    class Meta:
        db_table = 'child'
polls/templatetags/poll_extras.py
from django import template
from polls.models import Child

register = template.Library()

@register.filter
def fetch_object(sql):

    # childテーブル限定だがここも可変にしたい
    records = Child.objects.raw(sql)
    return records
templates/index.html
{% load poll_extras %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!-- 描画元から渡されキーを元にクエリを作成し、childオブジェクトを取得  -->

{{% with 'select id, name from child where id = '|add:child.id as sql %}
name: {% with sql|fetch_object as objects %}

<!-- childオブジェクトのプロパティを描画  -->
{% for object in objects %}
  {{ object.name}}, id: {{ object.id }}
{% endfor %}

{% endwith %}
{% endwith %}
</body>
</html>
発行されたhtml
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
name:Child1, id: 1
</body>
</html>

データ構造

childテーブル定義
       Table: child
Create Table: CREATE TABLE `child` (
  `id` varchar(20) NOT NULL,
  `name` varchar(20) DEFAULT NULL,
  `parent_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
childテーブルレコード
+----+--------+-----------+
| id | name   | parent_id |
+----+--------+-----------+
| 1  | Child1 |         1 |
| 2  | Child2 |         1 |
| 3  | Child3 |         1 |
| 4  | Child4 |         2 |
| 5  | Child5 |         2 |
| 6  | Child6 |         2 |
| 7  | Child7 |         3 |
| 8  | Child8 |         3 |
| 9  | Child9 |         3 |
+----+--------+-----------+

ハマったところ

  • QuerySet APIrawを使用する場合は必ずPKを取得しないといけない
  • 上記制約からraw以外のAPI使用が良い
  • デフォルトフィルタのaddは文字列と数値の足し算はできないため、その場合は空文字を返す
  • Django、python自体(入門者なのでエラー発生の切り分けがむずい)

参考サイト

0
0
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
0