Published Date : 2019年3月11日21:05
前回の記事の簡単なおさらい。
➀ models.pyを編集して管理者画面に
記事のタイトルを表示させる。
➁ Jinja2を使用して
Python変数を
HTMLに渡し、
ブラウザで表示できるようにする。
前回、作った
ブログページです。
このページを見やすいように
整えていきましょう。
postsのmodels.py
を開いてください。
前回作った、
Classファイル、
Postがあります。
以下を追加してください。
def summary(self):
return self.body[:30]
summary(要約)
という名前の関数を作り、
self.body
(記事の本文が入っている)
の先頭から30文字を
抜き出して表示させるようにします。
文字列[始まり:終わり]
これはスライスといって、
[:]の最初に何文字目から始めるか
何も指定しないとインデックス番号0番目、
つまり一番最初の文字が指定される
[:]終わりに何文字目で終了か
を数字で指定すると
何も指定しないとインデックス番号最後、
つまり一番最後の文字が指定される
文字をスライス(切り取って)
表示してくれます。
因みに、リストに対して
同じことをすると
リスト = ['spam','ham','bacon','egg','spam','spam']
リスト[1:4]
表示結果
['ham', 'bacon', 'egg']
インデックス番号の1番目
(リストの2番目、
0スタートなので)から
インデックス番号4番目の手前
(リストの4番目、
0スタートなので)から
終わりに関しては、
指定した数字の手前までが表示される。
さて、views.pyを保存して、
index.htmlの以下の部分を、
<p>{{ post.body }}</p>
views.pyで加えた
summary関数の名前に変えます。
<p>{{ post.summary }}</p>
保存してブラウザを更新すると、
(サーバーが起動していないなら、
以下のコマンドを打つ。)
python manage.py runserver
本文が短くなって表示されています。
続いて、画像を表示していきます。
大元のプロジェクトフォルダの
自分の場合はmysiteというフォルダ
urls.pyとsettings.py
を開きます。
因みに、mediaという
フォルダの中にはブログの
トップ画像が入っています。
mysite/settings.py
mysite/urls.py
まず、settings.pyから変更していきます。
STATIC_URL = '/static/'
上の1行に以下の2行を追加してください。
MEDIA_URL = '/pics/'
MEDIA_ROOT = BASE_DIR
このBASE_DIRとは、
settings.pyの
一番上のほうで、書いてあります。
これはosという
Python標準モジュールを使い、
settings.pyがある
パス(住所みたいなもの)を
とってきています。
__file__には
Python パラメータで指定した
ファイル名が入ってきます。
つまり、「settings.py」を
このように実行させた時
python settings.py
__file__には
「settings.py」
というパス名が入いります。
さらに進んで考えると
このように呼び出した場合
from django.conf import settings
settigns.BASE_DIR
__file__には
「settings.py」の名前が入ります。
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
絶対パスを取得します。
os.path.abspath(__file__)
絶対パスと
相対パスについての説明。
「image 2」は
現在いるフロアからみたら
すぐ近くにいるので、
/image 2で伝わります。
しかし外側からみた場合、
どっちのImage 2か分かりません。
そのような場合、
絶対パスを使います。
次のコードの意味は
ひとつ上のフォルダー名を取得します。
os.path.dirname()
つまり、settings.pyの絶対パスを取得し、
そのすぐ上のフォルダー名を取得し、
さらにすぐ上のフォルダ名を取得します。
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
os.path.abspath(__file__)
-> /user/document/mysite/mysite(djangoの特性上同じ名前のフォルダがある)/settings.py
os.path.dirname(os.path.abspath(__file__))
-> /user/document/mysite/mysite
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-> /user/document/mysite
結局のところ、
単にプロジェクトの
親元のフォルダまでの
パスを取得してるだけですが、
なぜこんな回りくどいことを
してるかというと、
このブログは最終的には
CORESERVERで用意された
レンタルサーバーにアップします。
その時、OSやフォルダを
置いている環境が
がらりと変わってしまいます。
そんなときにパスを
いちいち書き換えなくてすむように、
PythonでOS情報を取得して、
プロジェクトまでのパスを、
自動的に付け足してあげているわけです。
そして、BASE_DIRを分かりやすい名前、
MEDIA_ROOTとして
settings.pyに書きます。
MEDIA_ROOT = BASE_DIR
なぜ、直接BASE_DIRを
変数として渡さないかというと
単純に使いまわすためと、
他の機能を作ったときに
分かりやすくするためです。
例えば、ページングといった、
ページ送り機能を追加するときにも
ベースとなる
プロジェクトまでのパスは
必要になる場合があります。
そんな時に、画像はMEDIAで、
ページ送りはPAGEとすれば
あとで、何が書いてあるか
わかりやすくなるということです。
そして、さらに
MEDIA_URL = '/pics/'
を書き加えましょう。
この'/pics/'は
仮想フォルダといって、
実際にフォルダがあるわけではないです。
では何故こんなことをするかというと、
環境が変わっても
(例えばサーバー移転をしたさい)
以前の環境とまったく同じ動作
ができるようにするためです。
さらにいうと、
Djangoが画像配置のために、
わざわざこんな複雑なシステムにしてるのは
今はまださほど複雑な
アプリケーションを作ってはいませんが、
これが複数ページにまたがり、
色々な機能を追加して、
たくさんのデータベース情報
をとりあつかい、
一度にたくさんの
WEBリクエストを受け付けるなど
といったアプリケーションを作った場合に、
もし異なったアプリケーションで同じ名前の
静的ファイルが存在した場合、
Djangoが区別できなくなるばかりか、
管理している人間も混乱してきます。
そこで、STATICフォルダという場所に
仮想フォルダを作り、
そこに静的(画像ファイルなど変化のない)
ファイルを集約させて
Djangoが管理しやすいように
しているというわけです。
一旦保存をして、
お次は、urls.pyを書いていきます。
mysite/urls.py
以下のコードを
urls.pyに足してください。
from django.conf.urls.static import static
from django.conf import settings
さきほど説明した、
static(静的)ファイルを
Django側で設定するために必要。
そして、「settings.py」の
内容をインポートします。
そして、
このコードのすぐあとに
urlpatterns = [
path('admin/', admin.site.urls),
path('posts/',include('posts.urls')),
]
以下を書き加えてください。
+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
先程settings.pyで設定した、
MEDIA_URLを第一引数にして、
MEDIA_ROOT(プロジェクトまでのパス)を
キーワードで指定でした引数
(この場合、document_root)
root(ルート)とは根っこという意味。
に渡してあげる。
これによって、staticメソッドは
最初に、Postクラスで格納された
mediaフォルダ内にある画像を
静的ファイルとしてDjango側で
管理ができるようにして
動的(プログラム側が呼び出す)に
画像が表示できるようにしてくれます。
さて、あとはindex.htmlに
以下を付け足すだけです。
<img src={{ post.image.url }} style="width:100%;">
imgタグはsrc=でパスを指定すると
画像を表示してくれます。
styleで書かれている
style="width:100%;"
は、画像の横幅を100%
にするという意味で、
前回説明した、
Bootstrapのcontainer
classによって囲まれている
Divタグ内に
画像が収まるようになっています。
こうすることで、
綺麗に画像の横幅が統一されて、
多少の見栄えが確保されます。
ここまできたら、
書いたファイルをセーブして
ブラウザを更新しましょう。
例のごとく、
サーバーを止めてしまった人は、
python manage.py runserver
で起動させて、
http://127.0.0.1:8000/posts
とブラウザに入力して、
確認してみましょう。
それなりになってきましたが、
もうすこし、味をつけてみましょう。
タイトルをクリックしたら、
個別のページに飛ぶ、
ページング処理を考える
など細かい調整をしていきましょう。
あと、すっかり後回しに
なってしまいましたが、
CORESERVERへの
アップのしかたも
今週中にはできると
いいなと思ってます。
それでは、次回、
ページを整え、
個別のページに飛べるようにします。
See You Next Page !