DjangoBrothers BLOG ✍️

2019/01/21

このエントリーをはてなブックマークに追加
Django フロントエンド

Django VIEWやTEMPLATEでURLパス、クエリパラメーターを取得する方法

views.pyやHTMLファイル内で、アクセスされたURLを取得したり、取得したURLによって操作を切り替えたりする方法について説明します。

HttpRequestについて

Djangoはシステム間でやりとりするときに、「request」と「response」と呼ばれるオブジェクトを使って情報のやりとりをします。

通常、Djangoのシステムで何かしらのページにアクセスされた時(リクエストを受けた時)、そのリクエストにまつわる情報を持つHttpRequestというオブジェクトが生成されます。HttpRequestには、リクエストしてきたユーザーの情報などが含まれています。

そして、Djangoは適切なview関数を読み込んで処理を行うわけですが、その時、view関数の第一引数にHttpRequestが渡されます。

一般的には、view関数の第一引数にはrequestという名前をつけて扱うことが多いです。つまり、HttpRequestオブジェクトを「request」という名前で扱っていることになります。

HttpRequestオブジェクトは、様々な属性を持っており、例えばrequest.userのように書いてuser属性にアクセスすることで、ユーザー情報を取得することができます。これと同様に、URLに関する属性にアクセスすることで、URLのパスを取得することもできます。

パスを取得する

今回は、http://127.0.0.1:8000/search/?prefecture=tokyoというURLを例として、パスを取得する方法を紹介します。

まず、テンプレートファイルでURLを取得する例です。

search.html (http://127.0.0.1:8000/search/?prefecture=tokyo)

<!-- /search/ -->
<p>{{ request.path }}>/p>

<!-- /search/?prefecture=tokyo -->
<p>{{ request.get_full_path }}</p>

<!-- http://127.0.0.1:8000/search/?prefecture=tokyo -->
<p>{{ request.build_absolute_uri }}</p>

上から「ドメインを含まないフルパス」、「クエリパラメーターを含むパス」、「ドメインを含むパス」を取得することができます。

view側でも似たような感じで扱えます。

views.py

def search(request):
    path_1 = request.path
    path_2 = request.get_full_path()
    path_3 = request.build_absolute_uri()
    return render(request, 'home/search.html')

パスの中身によって処理を切り分けたい時などは、以下のようにできます。

views.py

def search(request):
    path_1 = request.path
    if "search" in path_1:
        print("パスに「search」という文字列が含まれてるときの処理")
    else:
        pass
    return render(request, 'home/search.html')

TEMPLATE側で条件分岐するときも同様。

search.html (http://127.0.0.1:8000/search/?prefecture=tokyo)

{% if 'prefecture' in request.get_full_path %}
    <p>クエリパラムに文字列「prefecture」が含まれる</p>
{% endif %}

ちなみにですが、Template側でrequestを扱うには、settings.pyでデフォルトで定義されている以下の記述が必要となります。

settings.py

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        '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',
            ],
        },
    },
]

クエリパラメーターを取得する

クエリパラメーターを取得するときは、requestのGET属性を使います。GET属性では、クエリパラメーターの値をdictのような形で取得することができます。

views.py (http://127.0.0.1:8000/search/?prefecture=tokyo)

def search(request):
    parameter = request.GET
    print(parameter)
    # <QueryDict: {'prefecture': ['tokyo']}>
    return render(request, 'home/search.html')

上記のようにrequest.GETで取得した値にアクセスしたいときは他のdictを扱うときと同様getメソッドなどが使えます。

views.py (http://127.0.0.1:8000/search/?prefecture=tokyo)

def search(request):
    prefecture = request.GET.get("prefecture")
    print(prefecture)
    # tokyo
    return render(request, 'home/search.html')

getメソッドは、値を取得できなかったときはNoneを返します。つまり、http://127.0.0.1:8000/search/のように、クエリパラメーターにprefectureがない状態でアクセスされた場合は、Noneが返り値となります。

views.py (http://127.0.0.1:8000/search/)

def search(request):
    prefecture = request.GET.get("prefecture")
    print(prefecture)
    # None
    return render(request, 'home/search.html')

ただ、getメソッドの第二引数には、デフォルト値を設定することができます。以下の例だと、クエリパラメーターにprefectureがなかった場合、「全国」という文字列を返すようになります。

views.py (http://127.0.0.1:8000/search/)

def search(request):
    prefecture = request.GET.get("prefecture", "全国")
    print(prefecture)
    # 全国
    return render(request, 'home/search.html')

詳細な情報はこちらにあります。