こんにちは、k_ukiです。現在Djangoで、卒業研究のWEBアプリケーション開発をしております。
その中で、モデルのpkに応じて内容を切り替える、詳細ページの作成をしました。また、複数のメソッドを掛け合わせる必要があったため、簡単に実装できる"class-based view"ではなく、拡張性の高い"function-based view"で実装をしました。今回は、その実装方法についてまとめていきます。
urls.pyを実装する
まずは、urls.pyを編集し、ルーティングと参照するviews.pyの関数を指定していきます。
from django.urls import path
from .views import detail_func
from . import views
urlpatterns = [
path('suggest_result/<int:pk>/', detail_func, name='search_word'),
]
urlの指定の際に書いてある <int:pk>は、渡すオブジェクトの主キーを表しています。例えば、「suggest_result/1」というurlにアクセスした場合、pkが1番のオブジェクトの詳細ページであることを示唆しています。
pathの第二引数である"detail_func"は、このurlにアクセスした際に参照する関数名を記載しています。今回だとviews.pyにあるdetail_funcを実行することになります。
pathの第三引数である「name='search_word'」は簡単にいうと「urlにアクセスするためのショートカットキー」のようなものです。renderなどで遷移する際にurlを入力する代わりに、ここに書いた文字列を指定することで画面を遷移することができます。※Railsに触れている人だと「名前付きパス」といった方が分かりやすいかもしれません。
views.pyを編集する
def detail_func(request, pk):
object = SearchWord.objects.get(pk=pk)
# viewに渡す物を辞書型配列に変換
context = {'object': object}
return render(request, 'search_word/suggest_result.html', context)
detail_funcの引数にrequestとpkの二つを指定しています。これらについて解説していきます。requestはページにアクセスしようとした際に送信されるHttpRequestオブジェクトのことです。例えば、urlがhttpなのかhttpsなのかといった情報が含まれます。また、第二引数のpkには、渡したいオブジェクトの主キーが入ります。ここでpkを受け取ることによって特定のオブジェクトを取得できるようになるのです。その特定のオブジェクトを取得しているのが下記のコードになります。
object = SearchWord.objects.get(pk=pk)
"SearchWord"は取得するモデル名のことです、"objects.get(pk=pk)"とすることによって、先ほど渡したpkを基にSearchWordモデルのオブジェクトを1件取得してくることができます。
次は以下のコードを見てみます。
context = {'object': object}
return render(request, 'search_word/suggest_result.html', context)
この二行で何をしているのか端的に説明するとtemplateに渡す情報を定義しそれをrenderで返しています。変数"context"では、templateに渡したいオブジェクトや変数を辞書型配列に変換し渡せるようにしています。辞書型であるため、渡したい変数が増えたとしてもその分keyとvalueを追加するだけで渡す変数を増やすことができます。
renderの部分では、左からリクエスト, 表示するhtmlファイル, 渡すオブジェクト等の情報の順で記載しています。この関数実行後はrenderの中に書かれた記述を基にtemplateが返され表示されます。
templateを編集
{% extends 'base.html' %}
{%block title%}実行結果 {%endblock%}
{% block content %}
<div class="container">
<div class="row">
<div class="col-lg-8">
<h2>実行結果</h2>
<table>
<tbody>
<tr>
<td>{{object.hoge}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
{% endblock content %}
テンプレートでは、渡したobjectを{{object.hoge}}とすることで出力しています。
さいごに
以上がfunction-based viewの詳細ページの実装方法になります。元々Railsを触っていた身からすると少し毛色が違い戸惑う箇所もありましたが、慣れてきたら以外に単純な構造であることが分かりました!