Django リダイレクト時に変数を渡す
約302日前
2021年7月19日22:01
デジタル
Django JavaScript
2021/7/19 投稿
Djangoを使った開発中に覚えたことを備忘録として残します。
今回はページをリダイレクトする際に好きな変数を次のビューに渡す方法を解説します。
最初にアクセスしたときだけメッセージを表示するページを作る。
今ちょうど食材を管理するアプリを作っていまして、「料理を作ったら、料理の実施履歴ページに移動する」部分を実装しています。
自動で履歴ページに移動した際に「調理しました!」というメッセージを表示させたいと思ったので、その機能を付けてみることにしました。
完成イメージはこんな感じです。
![]()
レシピ画面で人数と追加する食材を選んだ後、確定ボタンを押すと「履歴ページ」に移動する流れです。
あとからこの履歴ページにアクセスしても、「調理しました!」のメッセージは表示されません。
では実装方法をみていきましょう。
この機能の実装に利用したのは「Query String Parameters」というものです。
始めて聞く単語だと思うので簡単に説明します。
ネットサーフィンをしていると、たまに「https://example.com/?●●=▲▲&■■=★★」のように「?」で始まる文字がくっついたURLを見かけることがあると思います。
この?で始まる部分が「Query String Parameters」です。
![]()
上記の例では「?cooked=done」の部分が該当します。
「cooked」という変数に「done」という文字列が入っているイメージです。
変数が複数ある場合は「&」で繋げて書くことができます。
そしてなんと、このパラメーターがあっても無くても同じページが開きます!
「https://example.com/?●●=▲▲&■■=★★」は
「https://example.com/」と同じページが開き、ついでに変数「●●」と「■■」というパラメーターをもった状態になります。
このパラメータを上手く活用して目標を達成したいと思います。
「パラメーターがあっても無くても同じページが開く」という特徴を使って「最初にアクセスしたときだけメッセージを表示する」という機能を実装します。
やり方はこうです。
「料理をつくる」ボタンを押して履歴ページに移動する際のURLにはパラメーターを付与。
それ以外の場合、例えば料理履歴一覧ページから開くときはパラメーターを無しにします。
「パラメーターの有無」を検出して「メッセージの表示有無」を切り替えれば、上記の機能を実装できます。
上記の手段を用いるのであれば、レシピページから履歴ページへの移動時のみURLにパラメーターを付与する必要があります。
方法は2通りあります。
1つは使い慣れたリダイレクト関数「redirect()」を使う方法。
もう一方は「Ajax」処理の中でリダイレクトを行う方法です。
ではまず、redirect() を使う方法から。
やりたいことは移動先(リダイレクト先)のURLに「?●●=▲▲」を付けたいだけです。
ですので、流れとしては単純で
①移動先のURLを取得する
②URLに「?●●=▲▲」を付ける
③そのURLに移動する
ということになります。
まず始めに移動先ページのURLを取得しましょう。
別に直接書いちゃってもOKです。
続いてURLの最後に「?●●=▲▲」を付けます。
こちらも先ほどと同様に直接書いても良いですし、楽をしても良いです。
渡したい「変数」と「値」の組み合わせを下記だとします。
変数:cooked
値:done
付け足したい文字列は「?cooked=done」ですね。
上記の例だと
パラメーターの数が多い場合は2つ目の方法のほうがスマートだと思います。
最後に作ったURLへ移動します。
redirect()を使った方法は以上です。
続いて、「Ajax」処理の中でリダイレクトを行う方法を解説します。
Ajax処理でhtmlからviews.pyに戻ってきている場合、ビューの中でredirect()を使うことができません。
(エラーは出ませんが機能しないです)
仕方ないのでビューの中でリダイレクトはせず、htmlに再度戻ってからリダイレクトします。
続いてhtml側の処理です。
Ajaxでレスポンスが返ってきたところからです。
Djangoのテンプレート変数も普通に使えます。
「'/cookme/{{storage_id}}/history/'」
先ほどビューから受け取った変数も使えます。
「response.cooked_id」
最後にQuery String Parameterを手入力しています。
ここだけアナログです。
「'?cooked=done'」
上記の文字列はビューの中で作っておいて、変数としてJSONResponseで一緒に渡しても良いです。
その場合は下記のように書くと良いでしょう。
html側
Ajaxの場合の方法は以上です。
リダイレクト先のビューで先ほど定義したパラメーターを取得します。
URLにQuery String Parametersがある状態のときに、下記コードを実行すると変数を取得できます。
あとは「変数を取得したか否か」でメッセージを作る分岐を行います。
上記の例では、変数があった場合には「調理しました!」というメッセージを作っています。
最後に作ったメッセージをhtmlに渡します。
ビューから受け取ったメッセージを表示します。
htmlに先ほどのテンプレート変数「success_message」を書きます。
以上で、「最初にアクセスしたときだけメッセージを表示する」という機能を実装することができました!
今回のようにメッセージを表示したいときのベストな方法かは分かりませんが、知っている機能を組み合わせれば色々なことができます。
少しずつ知識を増やして、やりたいことが出来るようになるといいですね!
デジタル
Django JavaScript
改訂履歴
2021/7/19 投稿
1. 背景
Djangoを使った開発中に覚えたことを備忘録として残します。
今回はページをリダイレクトする際に好きな変数を次のビューに渡す方法を解説します。
2. ゴール
最初にアクセスしたときだけメッセージを表示するページを作る。
3. はじめに
今ちょうど食材を管理するアプリを作っていまして、「料理を作ったら、料理の実施履歴ページに移動する」部分を実装しています。
自動で履歴ページに移動した際に「調理しました!」というメッセージを表示させたいと思ったので、その機能を付けてみることにしました。
完成イメージはこんな感じです。
レシピ画面で人数と追加する食材を選んだ後、確定ボタンを押すと「履歴ページ」に移動する流れです。
あとからこの履歴ページにアクセスしても、「調理しました!」のメッセージは表示されません。
では実装方法をみていきましょう。
4. 実装方法
4.1 - Query String Parameters
この機能の実装に利用したのは「Query String Parameters」というものです。
始めて聞く単語だと思うので簡単に説明します。
ネットサーフィンをしていると、たまに「https://example.com/?●●=▲▲&■■=★★」のように「?」で始まる文字がくっついたURLを見かけることがあると思います。
この?で始まる部分が「Query String Parameters」です。
上記の例では「?cooked=done」の部分が該当します。
「cooked」という変数に「done」という文字列が入っているイメージです。
変数が複数ある場合は「&」で繋げて書くことができます。
そしてなんと、このパラメーターがあっても無くても同じページが開きます!
「https://example.com/?●●=▲▲&■■=★★」は
「https://example.com/」と同じページが開き、ついでに変数「●●」と「■■」というパラメーターをもった状態になります。
このパラメータを上手く活用して目標を達成したいと思います。
4.2 - URLの使い分け
「パラメーターがあっても無くても同じページが開く」という特徴を使って「最初にアクセスしたときだけメッセージを表示する」という機能を実装します。
やり方はこうです。
「料理をつくる」ボタンを押して履歴ページに移動する際のURLにはパラメーターを付与。
それ以外の場合、例えば料理履歴一覧ページから開くときはパラメーターを無しにします。
「パラメーターの有無」を検出して「メッセージの表示有無」を切り替えれば、上記の機能を実装できます。
4.3 - パラメーターの付与
上記の手段を用いるのであれば、レシピページから履歴ページへの移動時のみURLにパラメーターを付与する必要があります。
方法は2通りあります。
1つは使い慣れたリダイレクト関数「redirect()」を使う方法。
もう一方は「Ajax」処理の中でリダイレクトを行う方法です。
ではまず、redirect() を使う方法から。
やりたいことは移動先(リダイレクト先)のURLに「?●●=▲▲」を付けたいだけです。
ですので、流れとしては単純で
①移動先のURLを取得する
②URLに「?●●=▲▲」を付ける
③そのURLに移動する
ということになります。
まず始めに移動先ページのURLを取得しましょう。
別に直接書いちゃってもOKです。
url = reverse('app:next_view', kwargs={'key':value})
print(url)
>> https://exampe.com/next/value/ #取得例
#直接書く場合
url = "https://example.com/next/" + str(value) + "/"
print(url)
>> https://exampe.com/next/value/
どちらの場合も value は変数として解釈して下さい。
続いてURLの最後に「?●●=▲▲」を付けます。
こちらも先ほどと同様に直接書いても良いですし、楽をしても良いです。
渡したい「変数」と「値」の組み合わせを下記だとします。
変数:cooked
値:done
付け足したい文字列は「?cooked=done」ですね。
#直接書く場合urlencode()に引数として辞書を与えると、URLで使える形に直してくれます。
new_url = url + "?cooked=done"
#pythonらしく書く場合
parameter = {'cooked': done} #辞書で定義します
query_string_parameter = urlencode(parameter) #URLエンコードしてURLで使える形に変えます
new_url = url + "?" + query_string_parameter #合体
上記の例だと
query_string_parameter = urlencode(parameter)となります。
print(query_string_parameter)
>> "cooked=done"
パラメーターの数が多い場合は2つ目の方法のほうがスマートだと思います。
最後に作ったURLへ移動します。
return redirect(new_url)
redirect()を使った方法は以上です。
続いて、「Ajax」処理の中でリダイレクトを行う方法を解説します。
Ajax処理でhtmlからviews.pyに戻ってきている場合、ビューの中でredirect()を使うことができません。
(エラーは出ませんが機能しないです)
仕方ないのでビューの中でリダイレクトはせず、htmlに再度戻ってからリダイレクトします。
views.py #リダイレクト処理を行わないリダイレクト先のURLに<int:pk>のようなキーが必要な場合は、上記のように定義してhtmlに渡しておきます。
~~~色々な処理~~~
d = {
'cooked_id': cooked.cooked_uuid,
}
return JsonResponse(d)
続いてhtml側の処理です。
Ajaxでレスポンスが返ってきたところからです。
.done(response => {「window.location.href=」でリダイレクト先のURLを指定します。
window.location.href='/cookme/{{storage_id}}/history/' + response.cooked_id + '/' + '?cooked=done'
});
Djangoのテンプレート変数も普通に使えます。
「'/cookme/{{storage_id}}/history/'」
先ほどビューから受け取った変数も使えます。
「response.cooked_id」
最後にQuery String Parameterを手入力しています。
ここだけアナログです。
「'?cooked=done'」
上記の文字列はビューの中で作っておいて、変数としてJSONResponseで一緒に渡しても良いです。
その場合は下記のように書くと良いでしょう。
#下記query string parameterの定義方法は自由です
query_string_parameter = "/?cooked=done" #とりあえず手入力
d = {
'cooked_id': cooked.cooked_uuid,
'cooked': query_string_parameter, #変数として渡す
}
return JsonResponse(d)
html側
.done(response => {こんな書き方でできると思います。
window.location.href='/cookme/{{storage_id}}/history/' + response.cooked_id + response.cooked
});
Ajaxの場合の方法は以上です。
4.4 - パラメーターの取得
リダイレクト先のビューで先ほど定義したパラメーターを取得します。
URLにQuery String Parametersがある状態のときに、下記コードを実行すると変数を取得できます。
views.pyURLをパラメーターを取得するコードは「request.GET.get('URLの変数名')」です。
def HistoryDetailView(request, storage_id, cooked_id):
"""調理履歴詳細ページ"""
"""調理後か否か"""
after_cooked = request.GET.get('cooked')
#メッセージを作成
if after_cooked:
success_message = '<div class="alert alert-info" role="alert">調理しました!</div>'
else:
success_message = ""
#メッセージをhtmlに渡す
context = {
'success_message': success_message,
}
return render(request, template, context)
あとは「変数を取得したか否か」でメッセージを作る分岐を行います。
上記の例では、変数があった場合には「調理しました!」というメッセージを作っています。
最後に作ったメッセージをhtmlに渡します。
4.5 - メッセージの表示
ビューから受け取ったメッセージを表示します。
htmlに先ほどのテンプレート変数「success_message」を書きます。
{{success_message|safe}}htmlとして表示させたいので「safeフィルター」を用いています。
以上で、「最初にアクセスしたときだけメッセージを表示する」という機能を実装することができました!
5. さいごに
今回のようにメッセージを表示したいときのベストな方法かは分かりませんが、知っている機能を組み合わせれば色々なことができます。
少しずつ知識を増やして、やりたいことが出来るようになるといいですね!