Djangoで体重管理② 一覧画面(List)作成

前回、とりあえず Apache 上で Django を動かすところまで書きました。
以下のリンク先の設定をした前提で書いていきます。

https://benbenbase.dip.jp/ememory/2019/01/12/1505

結果として体重管理アプリができてます。

https://benbenbase.dip.jp/ememory/2019/02/05/1575

ではどうやってできたか見ていきましょう。
以下は私のイメージを元に記載しているので、プロから見ると”解釈がちがう!”と怒られるかもしれません。

まずは Model(データ項目)を考える。

設定
設定内容
[models.py]
from django.db import models                                           
                                                                       
# Create your models here.                                             
                                                                       
from django.db import models                                           
from django.utils import timezone                                      
                                                                                                                                             
class Post(models.Model):                                              
    author = models.ForeignKey('auth.User', on_delete=models.CASCADE)  
    weight_value = models.FloatField(null=True)                        
    text = models.TextField(blank=True)                                
    published_date = models.DateTimeField(                             
            default=timezone.now,                                      
            null=True,)                                                
                                                                       
    def publish(self):                                                 
        self.save()                                                    
                                                                       
    def __str__(self):                                                 
        return self.title
説明

体重管理なので当然 “体重” , “日付” は必要です。データ型も悩まず決まりますね。
あとは作成者とメモ欄です。
作成者はまぁ呪文だとして
メモ欄(text)はどのくらいの文字数を入れさせるか判断して型を決めましょう。
(null=True) は、作成済みDBにフィールドを作ろうとしたときに必要になります。
(blank=True) は、入力フォーム上で必須入力にしたくない時に使いましょう。

設定後の処理

DBにフィールドを作らなければいけないので、migrate しましょう。

(myvenv) $python manage.py makemigrations
(myvenv) $python manage.py migrate

ユーザーのアクセスからコンテンツ表示までの流れ

URLの設定

次に、よくViewを作成する手順に飛ぶんですが、私はわかりにくくて、ユーザーは URL にアクセスして view に飛ばされ、最終的に html を見るんだーというように書いていきます。
まずは設定を見てしまいましょう。

設定&説明

プロジェクト(“mysite”とします)のフォルダ直下にある urls.py を以下のようにすると、例えば http://FQDN/weight/ でアクセスできるようになります。
「この URL にアクセスがきたらアプリケーション weight の urls.py を参照してね」
という設定です。

設定内容
[mysite/urls.py]

from django.urls import include, path

urlpatterns = [
        path('weight/', include('weight.urls')),
]

次は アプリケーション側の urls.py を書きます。
トップページには毎日入力する体重の一覧とグラフを表示したいので List を表示させることにします。
その他、詳細画面(detail)・新規作成(new)・編集画面(edit)・詳細画面からレコードを削除する画面(remove)・グラフ画像用url(plot.png)・リスト画面から削除するためのurl(delete) を設定しています。

設定内容
[weight/urls.py]

from django.urls import path
from . import views

urlpatterns = [
    path('', views.post_list, name='post_list'),
    path('post/<int:pk>/', views.post_detail, name='post_detail'),
    path('post/new/', views.post_new, name='post_new'),
    path('post/<int:pk>/edit', views.post_edit, name='post_edit'),
    path('post/<int:pk>/remove', views.post_remove, name='post_remove'),
    path('post/plot.png', views.post_plot, name='post_plot'),
    path('delete', views.delete, name='delete'),
    ]

これで http://FQDN/weight/・・・ でアクセスした時にどの view に飛ばされるかが決まりました。

View(データの取り出し、加工) の開発

では次に view を見ていきましょう。
ちなみに、今回の設定は関数view です。クラスView を使ったほうが色々簡単にできるのですが関数viewを使っておいたほうが後々の為の勉強になると思います。
クラスviewの使い方は追々書いていきます。

設定
設定内容
[weight/views.py]
from django.http import HttpResponse
from django.shortcuts import render
from .models import Post

def post_list(request):
    postlist = Post.objects.filter(published_date__lte=timezone.now()).order_by('-published_date')
    return render(request,'weight/post_list.html',{'postlist':postlist})
説明

全部のViewを説明すると、とても長くなるので今回は一旦 List View だけ説明します。
urls.py で指定した views.post_list に対応する関数を作ります。
関数冒頭で現在よりも古い投稿日時のレコードを、Model で作成した Postから取り出しています。
order_by(‘published_date’)  で :マイナス を指定しているので新しい順に変数 postlist に格納しています。
次にhtmlファイルを指定しています。
データベースから取得した値を格納した変数 postlist を渡せるようにしています。
このhtmlファイルは template フォルダの下に作る必要があります。
Settings.py に以下のように記述しているので私の場合はプロジェクトのフォルダ mysite の下に template フォルダを作成して、その下にアプリケーション weight 用のフォルダを作ってその中に htmlファイルを作成しています。

[mysite/settings.py]
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join('/var/www/html/django/mysite', 'templates'),

Template(html)の作成

ようやくブラウザに表示する html を作成する段階に来ました。

設定

これも設定内容例を見てしまったほうが早いですね。
まだ私も改良を試みていますが、各ページが共通で使うCSSを読み込む記述やヘッダーなどを記述した base.html を作成することを推奨します。

base.html 設定内容
<!doctype html>
<html lang="ja">
 <head>
  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Weight Management</title>
  </head>
   <body>
    <div class="page-header text-nowrap">
     <h1><a href="/weight/">Weight Management</a></h1>
      </div>
       <div class="container-fluid">
       {% block content %}
       {% endblock %}
       </div>
      </body>
</html>
説明

普通のhtmlとくらべると赤字部分が django 特有の部分です。
色々な解説ページがあるのであまり書きませんが、例を言うと、views.py から呼び出される ‘template/weight/post_list.html’ 側から base.html を呼び出す時に使います。

では次は ‘template/weight/post_list.html’  の説明です。

post_list.html 設定内容
{% extends 'weight/base.html' %}

{% block content %}
<div class="table-responsive">
 <table>
  <thead>
   <tr>
    <th class="text-nowrap">Date,Time</th>
    <th class="text-nowrap">Weight</th>
    <th class="text-nowrap">Text</th>
   </tr>
  </thead>
 <tbody>
 {% for post in postlist %}
  <tr>
   <td class="text-nowrap"> <a href="{% url 'post_edit' pk=post.pk %}">{{ post.published_date }}</a> </td>
   <td class="text-nowrap"> {{post.weight_value}} kg </td>
   <td class="text-nowrap"> {{post.text}} </td>
  </tr>
 {% endfor %}
  </tbody>
 </table>
</div>
{% endblock %}

重要な所を赤字にしています。

{% extends ‘weight/base.html’ %}
views.py から呼び出されるのはこの html ファイルなので、このファイルから base.html ファイルを呼び出しています。

{% block content %}{% endblock %}
base.html の中にも書きましたね。base.html の該当部分にこの中のhtmlが埋め込まれます。

{% for post in postlist %}
“{% %}” で囲むことによって python を html の中に記述して実行することができます。
”postlist” は views.py でデータベースから取り出したデータが格納されている変数でしたね。
for文で ”postlist” の値が “post” に保存されるので、{{ post.published_date }} のように指定して値を取りだして html に書き出しています。
published_date は models.py に設定していますね。

一旦ここまで

Apache mod-wsgi を使っているようであれば、.pyファイルの変更を反映する為、Apacheのリロードなり再起動なりをしてください。wsgiが .pyファイルをキャッシュしている様子でwsgiをリロードしないと変更が反映されません。(htmlファイルの変更は即時反映)

データを入力しないとテーブルヘッダしか表示されないと思いますが、一旦ここまで。

これ以降はまた次回以降書きます。書くのに時間かかったー

タイトルとURLをコピーしました