個別ページの作成
前回はブログ記事を一覧で表示する機能を追加した。
今回はブログ記事の詳細を個別ページとして表示する機能を追加する。
現在のディレクトリ構成は以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
デスクトップ └Blog ├Blog_app │ ├migrations │ ├__init__.py │ ├admin.py │ ├apps.py │ ├models.py │ ├tests.py │ ├views.py │ ├urls.py │ └templates │ └Blog_templates │ ├index.html │ ├create.html │ └page_list.html ├db.sqlite3 ├config │ ├・・・ │ └urls.py ├env_blog └manage.py |
個別ページを作成する手順
urls.pyの編集
~デスクトップ/Blog/Blog_app/urls.py
1 2 3 4 5 6 7 8 9 10 11 |
from django.urls import path from .views import index, create, page_list, detail #[1] app_name = 'Blog_app' urlpatterns = [ path('', index, name='index'), path('index/', index, name='index'), path('create/', create, name='create'), path('page_list/', page_list, name='page_list'), path('detail/<int:pk>/', detail, name="detail"), #[2] ] |
[1]detailを追記
views.pyからdetail関数をインポート。
detail関数はブログ記事のうち1つを個別ページで表示するための関数。
views.pyにはまだdetail関数はないので次の手順で作成する。
[2]path関数を追記してURLパターンを追加
利用者が入力したURLと第一引数が一致した場合、第二引数のdetail(views.py内の関数)を呼び出す。
detail/<int:pk>/とあるが、detail/の後にint型の数字を受け取ることを示している。
pkはprimary keyの略で、ブログの各記事のIDを指す。
例えば以下の場合はpk(またはID)が1の記事を呼び出す。
views.pyの編集
~デスクトップ/Blog/Blog_app/views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
from django.shortcuts import render, get_object_or_404 #[1] from .models import Blog # Create your views here. def index(request): template_name = "blog_templates/index.html" return render(request, template_name) def create(request): template_name = "blog_templates/create.html" if request.POST: title = request.POST["title"] content = request.POST["content"] object_ = Blog(title=title, content=content) object_.save() return render(request, template_name) def page_list(request): template_name = "blog_templates/page_list.html" pages = Blog.objects.all() context = {'pages': pages} return render(request, template_name, context) #[2] def detail(request, pk): template_name = "blog_templates/detail.html" #page = Blog.objects.get(pk=pk) page = get_object_or_404(Blog, pk=pk) context = {'page': page} return render(request, template_name, context) |
[1]get_object_or_404を追加
get_object_or_404は個別のデータを取得する際に使用する関数。
django.shortcutsモジュールからインポートする。
モデルからオブジェクトを取得する際に、オブジェクトが存在しない場合に404エラーページを表示する。
[2]detail関数を作成
利用者がIDで指定した1つのブログ記事を、専用の個別ページ上で表示するためのデータを返す。
def detail(request, pk):
detail関数の宣言。第一引数はrequestで、利用者からのリクエストオブジェクトを受け取る。
第二引数はpk(primary key)で、利用者から受け取ったリクエストに含まれるブログ記事のpk(つまりID)を受け取る。
このpkは、urls.pyのpath関数に記述した<int:pk>のpkと一致していなければならない。
template_name = “blog_templates/detail.html”
template_nameにblog_templates内のdetail.htmlまでのアドレスを格納。
detail.htmlは未作成なので次の手順で作成する。
#page =Blog.objects.get(pk=pk)
page = get_object_or_404(Blog, pk=pk)
1行目のpage =Blog.objects.get(pk=pk)はモデルから指定したpkのオブジェクト(ブログ記事)を取得するために使用される。
この方法では、存在しないpkが指定された場合にDoesNotExistエラーが表示されてしまうので、404エラーを返すために2行目を使用。
2行目のpage = get_object_or_404(Blog, pk=pk)もモデルから指定したpkのオブジェクト(ブログ記事)を取得するために使用される。
存在しないpkが指定された場合は404エラーを返す。
context = {‘page’: page}
contextには辞書形式でデータを格納する。
キーとなるpage(左側)はhtmlファイルから呼び出す際に使用される。
バリューとなるpage(右側)にはモデルを通じてデータベースから取得した記事のデータが含まれており、htmlファイルで扱うことができる。
return render(request, template_name, context)
render関数を使ってリクエストに対するレスポンスを返す。
個別ページ(detail.html)の作成
~デスクトップ/Blog/Blog_app/temlates/blog_templates/detail.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>ブログ</title> </head> <!--[1]--> <body> <h1>詳細</h1> <a href="{% url 'Blog_app:index' %}">トップ</a><br> <a href="{% url 'Blog_app:page_list' %}">一覧</a><br> {{page.title}}<br> {{page.content}}<br> {{page.created_date}}<br> </body> </html> |
<h1>詳細</h1>
h1タグで詳細画面の見出しを作成
<a href=”{% url ‘Blog_app:index’ %}”>トップ</a><br>
Aタグを使ってトップページへのリンクを作成。
urls.pyのurlpatterns内にあるpath関数で、第三引数がname=indexとなっているものを呼び出す。リンクテキストはトップとしている。
また、brタグを追加して改行を行う。
<a href=”{% url ‘Blog_app:page_list’ %}”>一覧</a><br>
urls.pyのurlpatterns内にあるpath関数で、第三引数がname=page_listとなっているものを呼び出す。リンクテキストは一覧としている。
{{page.title}}<br>
タイトルを表示。
pageはviews.pyのdetail関数で変数contextに格納したキーであるpage。
Djangoのテンプレート(htmlファイル)ではデータを扱う時は{{ }}で囲む。
{{page.content}}<br>
記事の内容を表示。
{{page.created_date}}<br>
記事の作成日を表示。
作成日はmodels.pyでauto_now_add=Trueとなっているので、記事を作成したときに自動的に今日の日付が入っている。
一覧ページからリンクを作る
~デスクトップ/Blog/Blog_app/temlates/blog_templates/page_list.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>ブログ</title> </head> <body> <h1>記事一覧</h1> <a href="{% url 'Blog_app:index' %}">トップ</a><br> {% for page in pages %} <ul> <li>{{ page.title }}</li> <li>{{ page.content }}</li> <li>{{ page.created_date }}</li> <li><a href="{% url 'Blog_app:detail' page.id %}">詳細</a></li> <!--[1]--> </ul> {% endfor %} </body> </html> |
[1]一覧ページに各記事の詳細へのリンクを作成。
<li><a href=”{% url ‘Blog_app:detail’ page.id %}”>詳細</a></li>
Aタグを使ってブログ記事の詳細ページへのリンクを作成。リンクテキストは詳細としている。
Aタグ内のurlテンプレートタグでurls.pyのurlpatterns内でname=detailとなっているpath関数を呼び出している。
liタグで囲んでリストの1項目としている。
開発用サーバーを起動して確認
開発用サーバーを起動して、画像のように表示されていればOK
開発用サーバーの起動は以下のコマンドで行う。
~デスクトップ/Blog/
1 |
python manage.py runserver |
■一覧ページ
詳細というリンクテキストをクリックすると個別ページへ遷移することができればOK
■詳細ページ
トップページ、一覧ページへのリンクがあり、
タイトル、内容、作成日が表示されていればOK
ディレクトリ構成の確認
現在のディレクトリ構成は以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
デスクトップ └Blog ├Blog_app │ ├migrations │ ├__init__.py │ ├admin.py │ ├apps.py │ ├models.py │ ├tests.py │ ├views.py #編集 │ ├urls.py #編集 │ └templates │ └Blog_templates │ ├index.html │ ├create.html │ ├page_list.html #編集 │ └detail.html #新規作成 ├db.sqlite3 ├config │ ├・・・ │ └urls.py ├env_blog └manage.py |
urls.pyでは、URLがdetail/pkと一致する場合にviews.pyのdetail関数を呼び出すpath関数を追記した。また、このURLパターンをdetailと名付けた。
views.pyでは、detail関数を作成した。detail関数は、pkで指定されたオブジェクト(ブログ記事のデータ)を、blog_templatesディレクトリ内のdetail.htmlとあわせて利用者に聯本巣として返す。また、存在しないpkが指定された場合は404エラーを返す。
detail.htmlを新規作成した。detail.htmlは、views.pyから呼ばれた際にブログ記事の各データ(タイトル、内容、作成日)を表示する。
コメント