utamaro’s blog

誰かの役に立つ情報を発信するブログ

Djangoのtemplate内でクエリパラメータを設定する方法

Djangoのtemplate内で以下のように書いているときに、リンク先をクエリパラメータで渡すときの方法です。

<li><a href="{% url 'home' %}">next</a></li>

渡したいパラメータはpとします。値は整数です。

まず、一番簡単な方法を紹介します。

<li><a href="{% url 'home' %}?p=1">next</a></li>

この方法はシンプルですが、パラメータが増えたときに大変なことになります。

具体的には以下のようにどこからどこまでがパラメータとして設定しているのか分かりづらくなります。

{% url 'home' %}?p=1&s=23&d=201810&f=90

この問題を解決するための少し、面倒な方法を紹介します。

以下のようなディレクトリ構成でtemplate_tags/tags.pyというファイルを作成します。

.
├── manage.py
├── project
│   ├── __init__.py
│   ├── assets
│   ├── django.log
│   ├── settings
│   ├── templates
│   ├── urls.py
│   └── wsgi.py
└── template_tags
    ├── __init__.py
    └── tags.py

tags.pyの内容は以下のように書きます。

from django import template

register = template.Library()


@register.simple_tag
def query_transform(request, **kwargs):
    updated = request.GET.copy()
    for k, v in kwargs.items():
        updated[k] = v

    return updated.urlencode()

これはDjangoのcustom templateという機能で使えるものです。

https://docs.djangoproject.com/en/2.1/howto/custom-template-tags/

次に、settings.pyを修正します

librariesのところから追加します。

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR,  'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
            'libraries': {  # ← これを追加する
                'tags': 'template_tags.tags',
            }
        },
    },
]

最後に、template(html)を修正します。

どこでも良いのですが、以下の記述を書きます。

私の場合は<body>直下に書いています。

<body>
    {% load tags %}
    ...

tagsはlibraries.tagsの名称です。つまり、template_tags.tagsで登録しているタグを読み込むということです。

ではタグを使ってリンクを書き直します。

<li><a href="{% url 'home' %}?{%query_transform request p=1%}">next</a></li>

だいぶスッキリしました。

複数のパラメータを渡したい場合は{%query_transform request p=1 q=2%}となります。