見出し画像

Django_ModelとTemplateで簡単なリストページを作る

1.前回の記事

前回はDjangoのmodel(データベース)を実装を通じて学習しました。
models.pyにデータベーステーブルとアトリビュートの定義をコードし、
makemigrationsでテーブルの設計書を作成。さらにその設計書を元に
migrateを実行することで、テーブルを作成出来るのでした。

Django-ページ2 (1)


2.今回おこなう事

参考書籍の流れに沿ってBlogサイトをDjangoを使って実装していきたいと
思います。今回はListViewというクラスを継承して
「作成したコンテンツをリスト的に表示しているページ」を作成するための
準備・技術理解をしていきます。
(あくまで技術理解なので、レイアウト等は全く手を付けていません。)
「リスト的に表示しているページ」とはnote的には以下のような場所です。

画像2

私用する具体的な技術として、前回学習したmodel。そして新しい技術で
あるtemplateを使ってHTMLを生成していきます。
templateとはHTMLファイルを作成する元のような存在です。


3.参考書籍

前回から引き続き、次の書籍を参考にしています。
本当にわかりやすく、おすすめ出来るな~と思います。
今回のブログ記事では、書籍のP106以降の写経をやっていきつつ、
都度自分の思考を整理していきたいと思います。


4.ディレクトリ構造

今回の作業を最後まで行った際のディレクトリ構造は以下です。

[root@localhost ~]# tree /root/django/blogproject/ 
/root/django/blogproject/ 
├── blogpost 
│   ├── __init__.py 
│   ├── __pycache__ 
│   │   ├── __init__.cpython-36.pyc 
│   │   ├── admin.cpython-36.pyc 
│   │   ├── apps.cpython-36.pyc 
│   │   ├── models.cpython-36.pyc 
│   │   ├── urls.cpython-36.pyc 
│   │   └── views.cpython-36.pyc 
│   ├── admin.py 
│   ├── apps.py 
│   ├── migrations 
│   │   ├── 0001_initial.py 
│   │   ├── 0002_blogmodel.py 
│   │   ├── __init__.py 
│   │   └── __pycache__ 
│   │       ├── 0001_initial.cpython-36.pyc 
│   │       ├── 0002_blogmodel.cpython-36.pyc 
│   │       └── __init__.cpython-36.pyc 
│   ├── models.py 
│   ├── tests.py 
│   ├── urls.py 
│   └── views.py 
├── blogproject 
│   ├── __init__.py 
│   ├── __pycache__ 
│   │   ├── __init__.cpython-36.pyc 
│   │   ├── settings.cpython-36.pyc 
│   │   ├── urls.cpython-36.pyc 
│   │   └── wsgi.cpython-36.pyc 
│   ├── asgi.py 
│   ├── settings.py 
│   ├── urls.py 
│   └── wsgi.py 
├── db.sqlite3 
├── manage.py 
└── templates 
   └── list.html


5.環境セットアップ

まず、blogpostのurls.pyを以下の様に修正します。
これをすることで/listを指定してWebブラウザでアクセスしてきた場合
BlogList.as_view()クラスを実行してユーザに返す、というような処理を
指定することが出来ます。
※BlogListクラスは後程すぐ後に実装します。

from django.urls import path 
from .views import BlogList 

urlpatterns = [ 
   path('list/', BlogList.as_view()), 
]


次にblogpostのviews.pyを次の様に修正します。
BlogListクラスをListViewを継承して作成しています。
そして今回初めて学習するtemplateと前回学習したmodelを
指定しています。
※list.htmlは後で実装します。

from django.shortcuts import render 
from django.views.generic import ListView 
from .models import BlogModel 

# Create your views here. 
class BlogList(ListView): 
   template_name = 'list.html' 
   model = BlogModel

いったん図にしてイメージを固めておきます。
modelはデータベース(正確にはテーブル?)みたいなものなので、
データが入っています。そのデータをtemplateに当てはめていくことで、HTMLファイルを生成。そのHTMLファイルをユーザに提供している
という事みたいです。

Django-ページ4 (3)


最初にmodels.pyにコードを入力し、modelに入れこむデータの要素を
決定していきます。

下記のコードでは、BlogModelというデータベーステーブルの中にtitle,content,postdate,categoryというアトリビュートを入れこむという
事になります。
またcategoryというアトリビュートはCATEGORYという枠の中から選択する
様に設定をしているみたいです。
(HTMLのタグで言うところのdatalist(select)-optionタグのような設定を
しているのだと思えば理解しやすいかもしれません。
また、def __str__()~についてはadminの見え方を変える為の記述らしい)

from django.db import models 

CATEGORY = (('business', 'ビジネス'),('life', '生活'),('other','その他')) 
class BlogModel(models.Model): 
   title = models.CharField(max_length=100) 
   content = models.TextField() 
   postdate = models.DateField(auto_now_add=True) 
   category = models.CharField(max_length=50, choices=CATEGORY)
   
   #adminの見え方を変更するための設定  
   def __str__(self): 
       return self.title


-----脱線-----

ちなみにdatalist-optionを実際にHTMLで実装をしてみると
以下の様に書きます。

<input type="text" id=test list="example"> 
<datalist id="example"> 
 <option value="Web">フロントエンジニア</option> 
 <option value="DB">データベースエンジニア</option> 
 <option value="ServerNetwork">インフラエンジニア</option> 
</datalist>

これをWebブラウザで表示してみると以下のようになります。
以下の様に自由に文字を入力することが出来、

画像4

また、選択肢の中から選択することも出来ます。
※selectタグを使用すると上記画像の様に自由に入力出来ず、
 選択肢の中からしか入力する値を決めることが出来ません。
 今回のmodelはselectの方がイメージとして近いです。すみません。

画像5

--------------


models.pyで定義したデータベーステーブルの定義書を作成し、
さらにその定義書を元に、実際にデータベーステーブルを作成します。
まず定義書を作成するためにmakemigrationを実行します。

[root@localhost blogproject]# python manage.py makemigrations blogpost 
Migrations for 'blogpost': 
 blogpost/migrations/0002_blogmodel.py 
   - Create model BlogModel


次にmigrateを実行します。
これを実行することでデータベーステーブルが生成されました。

[root@localhost blogproject]# python manage.py migrate 
Operations to perform: 
 Apply all migrations: admin, auth, blogpost, contenttypes, sessions 
Running migrations: 
 Applying blogpost.0002_blogmodel... OK

作成されたデータベーステーブルは以下のようなイメージですね。
(直近でPostgreSQLをやってDBについて感覚掴んでおいてよかった。。。)

画像6


作成したBlogModelデータベースをadmin画面で管理するために、blogpost内のadmin.pyを次の様に変更します。
admin.site.registerにデータベーステーブルをコードすることでadmin管理
画面で確認することが出来るようになります。

from django.contrib import admin 
from .models import SampleModel, BlogModel 

# Register your models here.  
admin.site.register(SampleModel) 
admin.site.register(BlogModel)


admin管理画面でデータベーステーブルを確認出来るか
確認してみます。
まずrunserverを実行しWebサーバを立ち上げます。

[root@localhost blogproject]# python manage.py runserver 192.168.184.138:8000 
Watching for file changes with StatReloader 
Performing system checks... 
System check identified no issues (0 silenced). 
May 21, 2021 - 23:57:44 
Django version 3.2.3, using settings 'blogproject.settings' 
Starting development server at http://192.168.184.138:8000/ 
Quit the server with CONTROL-C.


admin管理画面を確認してみると以下の様にデータベーステーブルが
あることが分かります。

画像7


このadmin管理画面で実際にデータを登録してみます。
ADD BLOG MODELを押下します。

画像8

データを登録していきます。今回は以下2点を登録しました。
先程models.pyで指定したアトリビュートが入力出来ること、categoryは
選択式となっていることが分かります。

画像9

画像10


データベーステーブルにデータが登録されているのが分かりますね!

画像11


データベーステーブルは作成出来ました。
下記のイメージ図では赤枠部分ですね。
今度は青枠部分、つまりtemplateを作成していきたいと思います。

Django-ページ4 (3)2


templatesディレクトをmanage.pyと同じディレクトリに作成します。
その後、templatesディレクトリ配下に今回使用するtemplateである
list.htmlファイルを作成します。
今回使用するlist.htmlファイルの中身は以下になります。
全然HTMLっぽくなく、むしろかなりPythonコードっぽいです。。。(笑)

{% for item in object_list %} 
   {{ item.title }} 
   {{ item.content }} 
   {{ item.postdate }} 
   {{ item.category }} 
{% endfor %}


Pythonコードでも見慣れない部分がありますが、Django独特のコードの
仕方の様で、次のような意味があるようです。

{%%}:
テンプレートタグと呼ばれ、何らかの処理を行う場合に使用される
{{}}:
テンプレート変数と呼ばれ、データを扱う場合に使用される

また「object_list」というのはListViewで指定したmodel全てのデータを
リスト化しているもののようです。
改めてviews.pyを見てみると、BlogListというクラスがListViewを継承しているのであった。

from django.shortcuts import render 
from django.views.generic import ListView 
from .models import BlogModel
 
# Create your views here. 
class BlogList(ListView): 
   template_name = 'list.html' 
   model = BlogModel

そしてこのBlogListを見てみます。
これらの4つが1つの塊となってforループで処理をされているのかなと
実装していて感じました。

from django.db import models 

CATEGORY = (('business', 'ビジネス'),('life', '生活'),('other','その他')) 
class BlogModel(models.Model): 
   title = models.CharField(max_length=100) 
   content = models.TextField() 
   postdate = models.DateField(auto_now_add=True) 
   category = models.CharField(max_length=50, choices=CATEGORY) 
    
   #adminの見え方を変更するための設定  
   def __str__(self): 
       return self.title

ちょっと頭の中が混乱しそうだったので図式化します。

画像13


templateを作成したので、Webサーバを起動し、URL末尾を/listにして
Webブラウザからアクセスしてみると以下のようなスクショの様に表示
されていました。
データベーステーブルからデータを取得することが出来ていますが、
レイアウトはめちゃくちゃであることが分かります。これはHTMLファイル
ではあるものの、HTMLで何も装飾をしていない為ですね。

画像14


この状態で少し気になったのでHTMLファイルを取得して確認しました。
以下の様なHTMLファイルがDjangoにより生成され、それを私が
Webブラウザを通じてみていることが分かりました。

<p>や<h1>等のタグは無いけれど、<html><head><body>タグは
自動で割り振られているんだな~的な事を見て感動。

<!-- saved from url=(0033)http://192.168.184.138:8000/list/ -->
<html>

<head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>

<body>
 Django面白い
   Djangoを『Djangoのツボとコツが絶対にわかる本』を読んで
勉強しています。
   May 22, 2021
   business

   noteでアウトプットを習慣化しています
   インプットは大切ですけどアウトプットはもっと大切だと思うのです。
インプットは自分の内部世界しか変えることは出来ない
アウトプット自分の内部世界だけではなく、それを見た人間に印象を与えることが出来る。
それにアウトプットする為には論理思考を用いて説明する準備がいる。
大変だけど頭の中が整理されてオススメ。絶対にやった方が良い
   May 22, 2021
   other
</body>

</html>


上記のファイルにHTMLの要素を加え、よりそれっぽく表示する
様に調整します。
list.htmlファイルを以下の様に修正しました。

{% for item in object_list %} 

   <ul> 
   <li>{{ item.title }}</li> 
   <li>{{ item.content }}</li> 
   <li>{{ item.postdate }}</li> 
   <li>{{ item.category }}</li> 
   </ul> 
    
{% endfor %}


HTMLの<ul><ol><li>タグは以下のような使い方をします。

<ul>
 <li>国語</li>
 <li>数学</li>
 <li>英語</li>
</ul>

<ol>
 <li>絶対にやり遂げると決めること</li>
 <li>変わると心に誓う事</li>
 <li>転んでも必ず立ち上がること</li>
 <li>後ろを向かないこと。逃げないこと</li>
</ol>

画像15


templateを新しくした状態で再度Webブラウザで/listにアクセスしたら、
以下の様に少し見やすい状態になりました。

画像16

HTMLベースでも確認してみます。
HTMLタグが入っていることが分かりますね。

<!-- saved from url=(0033)http://192.168.184.138:8000/list/ -->
<html>

<head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>

<body>
 <ul>
   <li>Django面白い</li>
   <li>Djangoを『Djangoのツボとコツが絶対にわかる本』を読んで
勉強しています。</li>
   <li>May 22, 2021</li>
   <li>business</li>
   </ul>
   
   <ul>
   <li>noteでアウトプットを習慣化しています</li>
   <li>インプットは大切ですけどアウトプットはもっと大切だと思うのです。
インプットは自分の内部世界しか変えることは出来ない
アウトプット自分の内部世界だけではなく、それを見た人間に印象を与えることが出来る。
それにアウトプットする為には論理思考を用いて説明する準備がいる。
大変だけど頭の中が整理されてオススメ。絶対にやった方が良い</li>
   <li>May 22, 2021</li>
   <li>other</li>
 </ul>    
</body>

</html>

この記事が参加している募集

この記事が気に入ったらサポートをしてみませんか?