LoginSignup
0
1

DjangoテンプレートでQuerySetをJSに渡す

Last updated at Posted at 2024-04-18

テンプレートでQuerySet型の値をjavascriptに渡したい

配列型や辞書型なら以下の通りで渡せるが、QuerySet型の場合はそのまま渡せない。

const sample = {{ object|safe }}

テンプレートタグを自作して対策した。

テンプレートタグの作り方

まずは独自のテンプレートタグの作り方

  1. アプリフォルダにtemplatetagsフォルダを作成
  2. templatetagsに __init__.py の空ファイルを作成
  3. templatetagsに my_tags.py のファイル(名前は自由)を作成し、ここに独自のテンプレートタグを作成してく。
app
├── views.py
├── ...
└── templatetags
    ├── __init__.py
    └── my_tags.py

テンプレートタグの作り方

templatetags/my_tags.py
from django import template  # 必須

register = template.Library()  # 必須

@register.simple_tag  # 必須
def double_number(number):
    return number * 2

テンプレートでの使い方

sample.html
{% load my_tags %}  {# ← 呼び出し #}

<p>2倍にする {{ double_number num }}</p>  {# 「タグ名 引数」のように使用する #}

QuerySetを配列に変換

QuerySet型を配列に変換するテンプレートタグを作成していく。

templatetags/my_tags.py
from django import template

import json
from datetime import date, datetime, time
from decimal import Decimal
from django.utils.safestring import mark_safe

# date, datetime, time, decimalの変換関数
def json_serial(obj):
    if isinstance(obj, (datetime, date, time)):
        return obj.isoformat()
    if isinstance(obj, Decimal):
        return float(obj)
    raise TypeError ("Type %s not serializable" % type(obj))

register = template.Library()

@register.simple_tag
def queryset_to_json(queryset):
    ary = list(queryset.values())  # 1
    json_ary = json.dumps(ary, ensure_ascii=False, default=json_serial)  #2
    return mark_safe(json_ary)  #3
  1. list(queryset.values())
    クエリセット内のオブジェクトを辞書の配列に変換
  2. json.dumps(ary, ensure_ascii=False, default=json_serial)
    ここでjsonに変換する。しかしデータの中にオブジェクト(datetimeやdecimalなど)が含まれていると、エラーが発生するので、default=json_serial で変換の定義を行っている。ここでは date, datetime, time, decimal の変換を定義しているが、必要に応じて記述していく
  3. mark_safe(json_ary)
    HTMLエスケープを行わない

テンプレートでの使い方

sample.html
{% load my_tags %}

<script>
const sample = {% queryset_to_json object %};
</script>
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