Published Date : 2019年3月11日21:05

CORESERVERでDjangoのBLOGを作る
〜後半(Part8)〜



前回の記事の簡単なおさらい。

models.pyを編集して管理者画面に 記事のタイトルを表示させる。
Jinja2を使用して Python変数を HTMLに渡し、 ブラウザで表示できるようにする。





前回、作った ブログページです。

Responsive image

このページを見やすいように 整えていきましょう。




postsmodels.py を開いてください。

Responsive image

前回作った、 Classファイル、 Postがあります。

Responsive image





以下を追加してください。
    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

本文が短くなって表示されています。
Responsive image





続いて、画像を表示していきます。

大元のプロジェクトフォルダの
自分の場合はmysiteというフォルダ
urls.pysettings.py を開きます。
因みに、mediaという フォルダの中にはブログの トップ画像が入っています。
Responsive image

mysite/settings.py
Responsive image

mysite/urls.py
Responsive image





まず、settings.pyから変更していきます。

STATIC_URL = '/static/'

上の1行に以下の2行を追加してください。
MEDIA_URL = '/pics/'
MEDIA_ROOT = BASE_DIR

このBASE_DIRとは、 settings.py 一番上のほうで、書いてあります。
Responsive image

これは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か分かりません。
そのような場合、 絶対パスを使います。
Responsive image

次のコードの意味は ひとつ上のフォルダー名を取得します。
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やフォルダを 置いている環境が がらりと変わってしまいます。

そんなときにパスを いちいち書き換えなくてすむように、
PythonOS情報を取得して、 プロジェクトまでのパスを、 自動的に付け足してあげているわけです。



そして、BASE_DIRを分かりやすい名前、 MEDIA_ROOTとして settings.pyに書きます。
MEDIA_ROOT = BASE_DIR

なぜ、直接BASE_DIR 変数として渡さないかというと
単純に使いまわすためと、 他の機能を作ったときに 分かりやすくするためです。

例えば、ページングといった、 ページ送り機能を追加するときにも
ベースとなる プロジェクトまでのパスは 必要になる場合があります。
そんな時に、画像はMEDIAで、 ページ送りはPAGEとすれば
あとで、何が書いてあるか わかりやすくなるということです。




そして、さらに
MEDIA_URL = '/pics/'

を書き加えましょう。

この'/pics/' 仮想フォルダといって、
実際にフォルダがあるわけではないです。

では何故こんなことをするかというと、

環境が変わっても (例えばサーバー移転をしたさい)
以前の環境とまったく同じ動作 ができるようにするためです。

さらにいうと、 Djangoが画像配置のために、
わざわざこんな複雑なシステムにしてるのは

今はまださほど複雑な アプリケーションを作ってはいませんが、
これが複数ページにまたがり、 色々な機能を追加して、
たくさんのデータベース情報 をとりあつかい、
一度にたくさんの WEBリクエストを受け付けるなど
といったアプリケーションを作った場合に、
もし異なったアプリケーションで同じ名前の 静的ファイルが存在した場合、
Djangoが区別できなくなるばかりか、 管理している人間も混乱してきます。

そこで、STATICフォルダという場所に 仮想フォルダを作り、
そこに静的(画像ファイルなど変化のない) ファイルを集約させて Djangoが管理しやすいように しているというわけです。

Responsive image

一旦保存をして、

お次は、urls.pyを書いていきます。

mysite/urls.py
Responsive image

以下のコードを 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フォルダ内にある画像を
Responsive image

静的ファイルとしてDjango側で 管理ができるようにして
動的(プログラム側が呼び出す)に 画像が表示できるようにしてくれます。
Responsive image





さて、あとはindex.html 以下を付け足すだけです。
<img src={{ post.image.url }} style="width:100%;">

imgタグはsrc=でパスを指定すると 画像を表示してくれます。
styleで書かれている
style="width:100%;"

は、画像の横幅を100% にするという意味で、
前回説明した、 Bootstrapcontainer classによって囲まれている
Divタグ内に 画像が収まるようになっています。

こうすることで、 綺麗に画像の横幅が統一されて、
多少の見栄えが確保されます。

Responsive image





ここまできたら、 書いたファイルをセーブして
ブラウザを更新しましょう。

例のごとく、 サーバーを止めてしまった人は、
python manage.py runserver

で起動させて、 http://127.0.0.1:8000/posts
とブラウザに入力して、 確認してみましょう。
Responsive image

Responsive image

Responsive image





それなりになってきましたが、 もうすこし、味をつけてみましょう。

タイトルをクリックしたら、 個別のページに飛ぶ、
ページング処理を考える など細かい調整をしていきましょう。
あと、すっかり後回しに なってしまいましたが、
CORESERVERへの アップのしかたも
今週中にはできると いいなと思ってます。





それでは、次回、
ページを整え、
個別のページに飛べるようにします。

See You Next Page !