さとし日記

都内大学院生のブログ

一人でやる趣味が多いとこういう時に暇にならずに済んで良い

数学は新たに1分野勉強しようと思うと相当腰を据えてやる必要があるから、十分に時間が取れる良い機会でもある。

外国語は集中的にというより、毎日コツコツやっていった方が良い気もするけど、1日あたりの強度を増すことができる。

WEBアプリ作りも慣れないうちはかなり時間のかかる作業であり、さらにいくらでも創意工夫の余地がある。

筋トレと柔軟も習慣的に行っている行為の1つであり、これも家でできる。

普段やっていることは、休み時間に近くを散歩すること以外は自宅でもできることばかりだ。

 

前まで自室では中々集中できず、カフェなどに行っていたが、スタンディングデスクに変えてから、自室でも問題なくできるようになった。

 

インターネットに繋がったデバイスさえあれば、YouTubeでもSNSでも、無料で楽しめるコンテンツは山のようにある。

 

ニュースを見て、それに関連することを適当に調べているとあっという間に1日が終わる。

本はKindleでも読めるし、お金を掛けたくなかったら、著作権が切れた古典も公開されているので、それを読むのも楽しい。

著作権が切れたものの場合、YouTubeで検索すると朗読した動画が出てくるので、オーディオブックにもなる。

 

論文も無料で公開されるケースが増えてきたので、馴染みのない分野の論文をじっくり時間をかけて読む良い機会かもしれない。 

 

まぁいつでも不要不急の外出ができるようになるのが、一番良いんだけど。

 


 

というわけで以下は今日の作業メモ。

 

前回は、静的なファイルの配置を行ったので、その続きから。

 

まずは、投稿一覧のページから、それぞれの詳細ページ(タイトル、日付、写真、本文)に飛べるようにする。

その為に、それぞれの記事を識別するための番号をつけていく。そうすることで、あとで本文等を編集した後でも対応関係が崩れずに済む。

Djangoは、自動的にIDというフィールドを定義して、連番で管理しているので、それを利用していく。

 

index.htmlのテンプレートのforループ内において、
#{{ content.id }} :
を追加することで、投稿一覧のページのタイトルの前に、番号(ID)を追加することができる。

 

次にURLの設定をする。その為に、webappのurls.pyの編集をしていく。
現在は、contentsとadminしかないので、そこにIDの設定を加えていく。
urlpatternsの引数は[正規表現], [表示するページ]となるので、今回は、

url(r'^contents/(?P<content_id>[0-9]+)/$', views.content_detail, name="content_detail")

とする。


そして、現時点で、webapp/urls.pyにおいて、viewsというオブジェクトがないので、
from contents import views
を追加する。

 

続けて、これに伴い、views.pyにcontent_detailという関数を追加していく。

def content_detail(req, content_id):とし、返り値は、
return render(req, 'contents/content_detail.html', {'content_id': content_id})
とする。

 

そして、index.htmlと同じ階層に、content_detail.htmlを作る。

とりあえず、IDが正しく出力できるか確かめたいので、最小限のコードを追加する。

 

<!DOCTYPE html>
<html lang="ja-jp">

{{ content_id }}

</html>

 

指定した番号の投稿内容をオブジェクトとして指定し、表示させていく。

 

 

views.pyにおいて、renderでcontent_idを渡す設定をしており、それをテンプレートで表示していた。

これをidではなく、指定した番号のオブジェクトを渡すようにする。

 

その為にまずは、def content_detail(req, content_id):のreturnの前に、

content = Content.objects.get(pk=content_id)

を追加する。この「pk」はprimary keyの略で、indexの番号である。

 

また、returnのあとも、

render(req, 'contents/content_detail.html', {'content': content})
contentという変数にcontentというオブジェクトを渡す設定に書き換える。

 

そして、content.htmlの中身もこのcontentオブジェクトを用いて、
{{ content_id }}

{{ content.title }}
{{ content.published }}
{{ content.boby }} # 英単語としてbodyが正しいが、models.pyにおけるクラス定義の段階で誤記したままデータの統合を行ってしまったので、本webアプリ内ではbobyと記す。
に改変する。

 

すると、
http://127.0.0.1:8000/contents/[任意の番号]/
で投稿の内容を表示することができる。

 

ここにさらに<img src = "{{ content.image.url }}" />等を加えると、投稿の内容を表示することができる。

 

また、現在オブジェクトが存在しない場合は(例えばindex番号が4の時)、
DoesNotExist at /contents/4/
というエラーが出るので、
Page not found (404)
が出るようにする。

 

その為に、views.pyにおいて、
from django.shortcuts import renderを
from django.shortcuts import render, get_object_or_404
とget_object_or_404を追加する。
そして、
content = Content.objects.get(pk=content_id)

content = get_object_or_404(Content, pk=content_id)
と書き換える。

 

これでURLにindex番号を指定することで、各投稿に飛べるようになったが、次はトップページから各投稿に飛べるようにリンクを追加していく。

 

各タイトルにリンクを追加すれば良いので、index.htmlファイルにおいて、
{{ content.title }}
となっているところを
<a href = "{% url 'content_detail' content.id %}">{{ content.title }}</a>
とする。

 

また、これでちゃんと飛べるように、アプリケーションのurls.pyにおいて、ページの指定をする。
url(r'^contents/(?P<content_id>[0-9]+)/$', views.content_detail, name="content_detail")
とname=“content_detail"が入っていることを確認する。

するとリンクが追加されていることがわかる。 

 

f:id:satoshi86:20200330083620p:plain

タイトルへのリンクの追加


 ただ、現時点では、ページによって画像の大きさが異なっていたり、文字がはみ出してりしていて、見栄えが悪い。

f:id:satoshi86:20200330083835p:plain

画面に対して画像が小さい


 

 

f:id:satoshi86:20200330083731p:plain

画像がはみ出ている

 

ページの幅に合わせて表示ができるようにBootstrapを追加していく。


Bootstrapには、CSS, jQuery, Bootstrap.jsのようなUIライブラリがあるので、これらを活用していく。

 

Bootstrapの特徴は主に3点。

1. レスポンシブデザイン対応

スマホやタブレットなど、画面の違いに応じて最適化したページを表示できる。

 

2. オープンソース

既製のパーツ以外も使いたい時に、レイアウトのファイルなども公開されているので、自在にカスタマイズすることができる。

 

3. デザインテーマが入手可能

非常にデザイン性の高いテーマを使用することができる。

 

これらの特徴により、デザイン力がなくても見栄えの良いサイトを作ることができる

 

また、CSS, jQuery, Bootstrap.jsをダウンロードしてローカル環境に設置しなくても、クラウドサーバーから参照することができる。

Bootstrapのトップページ  → Get started → Starter template
から、必要な部分を参照し、貼り付けていく。

 

まずは、CSSの追加。
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

をindex.htmlのheadタグの中に貼り付ける。

 


次にJavaScript(jQuery)のコードを追加する。

<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin=“anonymous"></script>

bodyタグを閉じる(</body>)前のところに追加する。

 

 

次にナビゲーションバーを追加する。

ComponentsNavbar

から適当に選び、見出しタグの前にペーストする。

 

 

<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href=“#”>Navbar[ここは改変]</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>

<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>

 


Navbarとなっているところは適宜改変する。

 

 

そしてナビゲーションとコンテンツを区別する為に、
見出しタグの前に
<div class ="container">
を追加する。そして</body>の前で、</div>で閉じる。

 

するとナビゲーションバーが追加されていることがわかる。

 

f:id:satoshi86:20200330083507p:plain

ナビゲーションバーの追加。テーマはlightからdarkに変更した。

 

続きはまた次回。