概要
今までデーターを保存するデーターベースとの連動やデーターを生成して読んで更新して削除(CRUD - Create Read Update Delete)する方法、そしてユーザーが接続するURLを生成する方法などジャンゴ(django)でウェブサービスをするための色んなことを見てみました。今回のブログではユーザーに見せるウェブページを作るためジャンゴ(django)のビュー(View)を使う方法について見てみます。
このブログはシリーズです。下記のリンクでシリーズの他の記事を見ることができます。
- ジャンゴ(django)インストール
- ジャンゴ(django)のプロジェクト開始
- ジャンゴ(django)のモデル(models)の使い方
- ジャンゴ(django)の管理者ページ
- ジャンゴ(django)のルーティング(Routing)
- ジャンゴ(django)のORM
- ジャンゴ(django)のビュー(View)
- ジャンゴ(django)のフォーム(Form)
- ジャンゴ(django)プロジェクトをヘロク(Heroku)へアップロードする
また、このブログシリーズで説明したソースコードはgithubに公開されております。下記のリンクで確認できます。
URL確認
以前のブログ(ジャンゴ(django)のルーティング(Routing))で私たちはユーザーが接続するURLと静的HTMLを連結する方法についてみてみました。下記のジャンゴ(django)コマンドを実行してテストサーバーを起動した後、http://127.0.0.1:8000/
に接続するとHello World
が表示されるウェブページを確認することができます。
# source venv/bin/activate
# cd django_exercise/
python manage.py runserver
データー伝達
以前のブログ(ジャンゴ(django)のORM)で生成したデーターをウェブページで見せるためビュー(View)にデーターを伝達してみます。blog/views.py
ファイルを開いて下記のように修正します。
from django.shortcuts import render
from .models import Post
def posts(request):
posts = Post.objects.filter(published_at__isnull=False).order_by('-published_at')
return render(request, 'blog/posts.html', {'posts': posts})
from .models import Post
: 私たちが作ったPost
モデル(Models)を読んできます。posts = Post.objects.filter(published_at__isnull=False).order_by('-published_at')
published_at__isnull=False
: published_atフィールドがnullじゃない場合(__isnull=False
)のデーターを持ってきます。order_by('-published_at')
: データーをpublished_at
フィールドで降順でソーティングします。
return render(request, 'blog/posts.html', {'posts': posts})
: 持ってきたデーターをblog/posts.html
ページに{'posts': posts}
でposts変数で送ります。
データー表示
上で伝達したデーターを画面に表示する方法についてみてみましょう。blog/templates/blog/posts.html
を開いて下記のように修正します。
<html>
<head><title>Hello World</title></head>
<body>
{% for post in posts %}
<div>
<h1>
{{ post.title }}<small>(published: {{ post.published_at }})</small>
</h1>
<p>{{ post.content | linebreaksbr }}</p>
</div>
{% endfor %}
</body>
</html>
{% for post in posts %}...{% endfor %}
: 上でblog/views.py
に伝達したposts
データーリストからpost
でデーターを一つずつ持てくるループです。{{ post.title }}<small>(published: {{ post.published_at }})</small>
: postデーターのtitle
/published_at
フィールドを表示します。 데이터를 표시합니다.<p>{{ post.content | linebreaksbr }}</p>
: postデーターのcontent
を持って来て改行(\n
)を改行タグ(<br/>
)に変換して表示します。
上のようにコードを修正してhttp://127.0.0.1:8000/
に接続すると下記のようにデーターが表示されることが確認できます。
もっと練習するため、詳細ページを作ってみましょう。上で作ったblog/templates/blog/posts.html
を下記のように修正します。
<html>
<head><title>Hello World</title></head>
<body>
{% for post in posts %}
<a href="{% url 'post_detail' id=post.id %}"> <!-- <<<<<<<<<<<<<<<<<<<<< here -->
<h1>
{{ post.title }}<small>(published: {{ post.published_at }})</small>
</h1>
<p>{{ post.content | linebreaksbr }}</p>
</a> <!-- <<<<<<<<<<<<<<<<<<<<< here -->
{% endfor %}
</body>
</html>
{% url 'post_detail' id=post.id %}
: 私たちが定義したdjango_exercise/urls.py
とblog/urls.py
でpost_detail
の名前(name)を探して当該URLで変換します。この時id
と言うパラメーターを作ってPost
のidを入れます。
まだ、post_detail
とマッチングされるURLを作ってないです。今からpost_detail
を対応するURLとビュー(View)を作ってみましょう。blog/templates/blog/post_detail.html
を作って下記のように修正します。
<html>
<head><title>Hello World</title></head>
<body>
<a href="{% url 'posts' %}">
Post List
</a>
<h1>
{{ post.title }}
</h1>
<p>created: {{ post.created_at }}</p>
<p>updated: {{ post.updated_at }}</p>
<p>published: {{ post.published_at }}</p>
<p>author: {{ post.author.username }}</p>
<p>{{ post.content | linebreaksbr }}</p>
</body>
</html>
{% url 'posts' %}
: URLファイルでposts
と言う名前(name)を持ってるURLを探してそのURLで変換します。author: {{ post.author.username }}
: 私たちが作ったPost
モデルとジャンゴ(django)が基本的提供してるauth.User
と連結して作者(author
)フィールドを作りました。このように連携してるモデル(Models)からusername
を持って来て表示することもできます。
画面に表示するページが準備できました。blog/urls.py
を開いて下記のように修正します。
from django.urls import path
from . import views
urlpatterns = [
path('', views.posts, name='posts'),
path('post/<int:id>/', views.post_detail, name='post_detail'), # <<<<<<<<<<<< here
]
post/<int:id>/
: URLにパラメーターで来た数字のデーターであるid
を表示します。name='post_detail'
: URLの名前はpost_detail
で、views.post_detail
とマッピングされています。
これで{% url 'post_detail' id=post.id %}
を使ったらpost/<int:id>/
のURLを表示してviews.post_detail
とマッピングする準備が終わりました。blog/views.py
ファイルを開いて下記のように修正します。
from django.shortcuts import render, get_object_or_404 # <<<<<<<<<<<< here
from .models import Post
def posts(request):
posts = Post.objects.filter(
published_at__isnull=False).order_by('-published_at')
return render(request, 'blog/posts.html', {'posts': posts})
# <<<<<<<<<<<< here
def post_detail(request, id):
post = get_object_or_404(Post, id=id)
return render(request, 'blog/post_detail.html', {'post': post})
get_object_or_404
: ジャンゴが基本的提供するファンクションを追加します。このファンクションは当該オブジェクト(Object)からデーターを持って来るがデーターがない場合404
エラーを発生するファンクションです。def post_detail(request, id):
: 新しく追加したURLとマッピングするファンクションです。パラメーターで渡したid
を別の変数でもらえます。
これで詳細ページを作ってみました。http://127.0.0.1:8000
に接続したら以前と違って下記のようにリンクがあるページが見えます。
当該リンクを押したら詳細ページURL(http://127.0.0.1:8000/post/2/
)に移動して下記のようにPost
の詳細ページが見えます。
テンプレートファイル
ビュー(View)とURL、そしてデーターを表示する方法にはちょっと慣れた気がします。しかし、HTMLファイルに重複するコードがたくさん見えます。まだ、css, js
やmeta
タグがないから大丈夫ですが、このタグがドンドン多くなったら重複するコードが増えます。このような重複部分を新しファイルで作って持って来る方法についてみてみます。
一旦、静的ファイル(css, js 등
)を追加する方法についてみてみます。blog/static/css/main.css
ファイルを生成して下記のように修正します。
h1 {
color: red;
}
このブログではデザインの部分は説明しません。もっと美しくウェブページを作りたい方はこのファイルを修正してください。ジャンゴ(django)はstatic
と言う名前のフォルダを自動に探して登録するので追加的登録作業をする必要はありません。
じゃblog/templates/blog/layout.html
ファイルを作って下記のように修正します。
{% load static %}
<html>
<head>
<title>Hello World</title>
<link rel="stylesheet" href="{% static 'css/main.css' %}" />
</head>
<body>
{% block content %} {% endblock %}
</body>
</html>
{% load static %}
: このファイルからstatic
フォルダを使えようにstatic
フォルダを読んで来ます。<link rel="stylesheet" href="{% static 'css/main.css' %}" />
: 私たちが読んできたstatic
フォルダからcss/main.css
を探してそのURLに変換します。{% block content %} {% endblock %}
: このレイアウト(layout)ファイルに必要なデーター(content
)を表示する位置を設定します。このように表示したい部分をblock [name]
で設定してそのブロック(block)を変換する部分を[name]
を使って作ります。
レイアウト(layout)ファイルを使うためblog/templates/blog/posts.html
ファイルを開いて下記のように修正します。
{% extends 'blog/layout.html' %}
{% block content %}
{% for post in posts %}
<a href="{% url 'post_detail' id=post.id %}">
<h1>
{{ post.title }}<small>(published: {{ post.published_at }})</small>
</h1>
<p>{{ post.content | linebreaksbr }}</p>
</a>
{% endfor %}
{% endblock %}
{% extends 'blog/layout.html' %}
: このファイル(posts.html)は私たちが作ったレイアウト(layout.html)ファイルを使います。{% block content %}...{% endblock %}
: 私たちがレイアウト(layout.html)ファイルに作ったブロック(block)、そこで名前がcontent
であるブロック(block)をここで作成した内容で変換します。
そしてblog/templates/blog/post_detail.html
ファイルを開いて下記のように修正します。
{% extends 'blog/layout.html' %}
{% block content %}
<a href="{% url 'posts' %}">
Post List
</a>
<h1>
{{ post.title }}
</h1>
<p>created: {{ post.created_at }}</p>
<p>updated: {{ post.updated_at }}</p>
<p>published: {{ post.published_at }}</p>
<p>author: {{ post.author.username }}</p>
<p>{{ post.content | linebreaksbr }}</p>
{% endblock %}
上で説明した内容と同じようにレイアウト(layout.html)ファイルを使って名前がcontent
であるブロック(block)をここで作成した内容で変換します。
確認
今まで作成した内容を確認するためhttp://127.0.0.1:8000/
に接続してみます。そしたら私たちが作成したcss
が適用された画面が下記のように見えます。(画面が上手く表示できない方はテストサーバーを再起動してください。)
リンクを押して詳細ページ(http://127.0.0.1:8000/post/2/
)に移動しても下記のようにcss
が適用されたことが確認できます。
これで私たちはジャンゴ(django)のテンプレートを活用して静的ファイル(css, jsなど)を持って来る方法とHTMLの重複を減らすための方法についてみてみました。
完了
今回のブログでジャンゴ(django)のビュー(View)を使う全般的方法についてみてみました。データーを持って来て画面に表示して、表示される画面を管理するためのジャンゴ(django)のテンプレートを確認してみました。また、cssとjsような静的ファイル(static)を持って来る方法もみてみました。もう、私たちはこれを使って一般的なウェブサービスサイトを作れるようになりました!
私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!
アプリ広報
Deku
が開発したアプリを使ってみてください。Deku
が開発したアプリはFlutterで開発されています。興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。