Non-engineer memoblog

エンジニアではない人間のメモブログ(備忘録とアウトプット欲のために)

Django2.0入門(その2)

Django2.0の環境が整ったため、さっそくDjangoプロジェクトを作成。
淡々とメモをしていますが、かなり躓き試行錯誤しながらやっていました。。。
(コピペではなく写経していたので、タイポとエラーと戦いつつ)

以下の学習コンテンツを参考
www.udemy.com
最初にもお伝えしましたが、この学習コンテンツは口頭での解説も分かりやすいので、初心者にはかなりオススメです。


setting.pyを編集

$ cd /home/hogeuser/projects/mircroblog/mircroblog/
$ sudo vim settings.py

settings.py

# 33行目辺りに blog を追加
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog',
]

# 107行目辺りを以下のように編集
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'

models.pyを編集

from django.db import models


class Blog(models.Model):
    '''
    - データを保存する場合は django.models だと「 ***Field() 」という形になることが多い
    - コードには記載が無いが、django内部的にIDがインクリメントで保存されている(PK:プライマリキー)
    '''

    # 文字列を保存する「models.CharField(max_length=保存する文字数)」
    content = models.CharField(max_length=140)

    # 日付を「post_date」に保存(「auto_now_add=True」で投稿したときに1度だけ日時を返す)
    post_date = models.DateTimeField(auto_now_add=True)
    # models.DateTimeField(auto_now=True) <-- 更新するたびに日時を上書きする

マイグレーションファイルを作成

$ python manage.py makemigrations

# DBをマイグレートする
$ python manage.py migrate


admin.pyの編集

$ cd blog/
$ sudo vim admin.py

admin.py

from django.contrib import admin

# 「models.py」で作成したBlogクラスをモジュールとしてインポート
from blog.models import Blog

# Blogクラスを継承 → アドミンサイトに登録
admin.site.register(Blog)


ListViewを作成

from django.shortcuts import render

# 汎用ビューのListViewをインポートする
from django.views.generic import ListView

# BlogListViewを作成したモデル「models.py」に関連付ける必要があるためにBlogモデルをインポートする
from .models import Blog

# ListViewクラスを継承したBlogListViewクラスを作成(クラス名は「App-nameListView」?みたいにする)
class BlogListView(ListView):
    # BlogListViewクラスをBlogモデルに関連付ける
    models = Blog

blog_list.html を作成

####### blog_list.html ##########
<html>
<head>
    <title>MicroBlog</title>
</head>
<body>

<h1>MicroBlog</h1>

<!-- 以下の<div>内にデータが入る -->
<div>

    <!-- {%}: プログラム的な命令を記述する(表示されない) -->
    <!-- 以下の「object_list」は「class Blog(models.Model):」のobjectのこと(idが降られてる1つ1つの記事) -->
    {% for blog in object_list %}
        <div>
            <!-- 二重 : 値を表示するための記述(表示される) -->
            {{ blog.content }}<br>
            {{ blog.post_date }}
        </div>
    <!-- PythonのインデントをHTML内で表現するために書く{%}内に「endhoge」 と書く -->
    {% endfor %}  

</div>

</body>
</html>


DetailViewを作成

###### views.py内に追記する ######

from django.shortcuts import render

# 汎用ビューのListViewをインポートする
from django.views.generic import ListView

# 汎用ビューのDetailViewをインポートする
from django.views.generic import DetailView

# BlogListViewを作成したモデル「models.py」に関連付ける必要があるためにBlogモデルをインポートする
from .models import Blog


# ListViewクラスを継承したBlogListViewクラスを作成
class BlogListView(ListView):
    # BlogListViewクラスをBlogモデルに関連付ける
    model = Blog

class BlogDetailView(DetailView):
    model = Blog


urls.pyを編集

###### urls.py内に追記 ######

from blog.views import BlogDetailView

urlpatterns = [
    #path(‘<URL>‘, views(関数), ニックネーム),  <--末尾に「,」を付ける(リスト[]のため)
    path(‘’, BlogListView.as_view(), name=“index”),

    #path(‘<pk ←IDのこと >‘, views(関数), ニックネーム),  <--末尾に「,」を付ける(リスト[]のため)
    path(‘<int:pk>’, BlogDetailView.as_view(), name=“detail”),

    path(‘admin/’, admin.site.urls),
]
<html>
<head>
<title>MicroBlog</title>
</head>
<body>

<h1>MicroBlog</h1>

<!-- 以下の<div>内にデータが入る -->
<div>

    <h2>{{ object.content}}</h2>
    <p>{{ object.post_date }}</p>

</div>

</body>
</html>

base.htmlを作成

<!-- 「block body」と「endblock」の記述が重要  -->

<html>
<head>
<title>MicroBlog</title>
</head>
<body>

<h1>MicroBlog</h1>

<!-- 以下の<div>内にデータが入る -->
<div>

    <!-- 以下の「block body」は以下の部分(base.html)は上書きされますよというもの-->
    <!-- もし上書きされなかったら「block body」と「endblock」の間のベーステンプレが表示される-->
    {% block body %}
        <p>base.html</p>
    {% endblock %} 

</div>

</body>
</html>

テンプレファイルを作成

# テンプレ化させたいHTMLファイルの一番上に以下の記述を行う
{% extends “base.html” %}

{% block body %}

{% endblock %}


# たとえばblog_list.html内特有の記述(表示)をベースとなるテンプレ(base.html)に統合させたい場合は以下。
{% extends “base.html” %}

{% block body %}

    # 以下に特有の記述をコピペする    
    {% for blog in object_list %} 
        <div>
            {{ blog.content }}<br>
            {{ blog.post_date }}
        </div>
    {% endfor %}  

{% endblock %}

# それ以外は「base.html」に記載があるので全て削除


# blog_detail.html内特有の記述(表示)を「base.html」に統合。そして、それ以外の記述は全て削除
{% extends “base.html” %}

{% block body %}
    <h2>{{ object.content}}</h2>
    <p>{{ object.post_date }}</p> 
{% endblock %}


'''
Bootstrapをダウンロードして、「index.html」を「base.html」に全てコピペ(上書き)する。
そしたら、main contents箇所を削除(divは残す)
さらにfooterも削除(ただし残しても良い)
'''

Bootstrapを追加していく

日本語も美しく表示できるBootstrapテーマのRINを追加していく(学習コンテンツでは別のテーマを使用していましたが)
rinhoshizo.la

Bootstrap自体の知識もあんまりないので、結構は大変だった。。。


Bootstrapを修正

# base.htmlの一番上に以下を追記する

{% load static %}

<!DOCTYPE html>
<html lang=“en”>

'''
プログラム的に内容が変更されない静的なファイル(CSSとか画像とか)を保存されているフォルダへ自動的にPATHを通してくれる記述。
'''
    
# 以下のように加筆をしていく

<!-- Bootstrap core CSS -->
<link href=“{% static ‘vendor/bootstrap/css/bootstrap.min.css’ %}” rel=“stylesheet”>

<!-- Custom styles for this template -->
<link href=“{% static ‘css/clean-blog.min.css’ %}” rel=“stylesheet”>

<!-- Bootstrap core JavaScript -->
<script src=“{% static ‘vendor/jquery/jquery.min.js’ %}“></script>

<script src=“{% static ‘vendor/bootstrap/js/bootstrap.bundle.min.js’ %}“></script>

<!-- Custom scripts for this template -->
<script src=“{% static ‘js/clean-blog.min.js’ %}“></script>


'''
これは「settings.py」の一番下に記述されて言う「STATIC_URL = /static/」の記述以降に
 /static/vendor/bootstrap/css/bootstrap.min.css  となるように記述がされる
 この「STATIC_URL = /static/」の「/static/」の箇所を修正するだけで、AWSから配信する際のPATHの変更が簡単になる
'''

# 「“{% static 〜〜」 の記述を有効にするために、「settings.py」の一番下へ追記

STATIC_URL = ‘/static/’
STATICFILES_DIRS = (
    os.path.normcase(os.path.join(BASE_DIR, “assets”))
)

BASE_DIRについて

#「BASE_DIR」とは「/home/hogeuser/projects/microblog/microblog」のことで、

    microblog/   # <--- つまりはこいつのこと
    ├── assets
    ├── blog
    │   ├── __init__.py
    │   ├── admin.py
    │   ├── apps.py
    │   ├── forms.py
    │   ├── migrations
    │   ├── models.py
    │   ├── templates
    │   ├── tests.py
    │   └── views.py

'''
つまりは「os.path.normcase(os.path.join(BASE_DIR, “assets”))」は、
/home/hogeuser/projects/microblog/microblog/assets」のように
「assets」ディレクトリのPATHを通すという記述。
Djangoはフルパスで指定する必要があるため、「os.path.join」でプログラム的にパスを作成している
'''

テンプレファイルについて

'''
現在はBlogクラスを作った場合は、
「blog_list」や「blog_detail」や「blog_hoge」などのファイルを探すという決まりがある。

しかし色々と別のフォルダを作ってそこにファイルを置きたい場合は、
「settings.py」の「TEMPLATES」の「‘DIRS:’」にPATHを記述する必要がある。
'''

# 例: microblog/templatesというフォルダを作り、その中にあるファイルを見つけて欲しい場合

TEMPLATES = [
    {
        ‘BACKEND’: ‘django.template.backends.django.DjangoTemplates’,
        ‘DIRS’: [
            os.path.normpath(os.path.join(BASE_DIR, “templates”))
        ],
        ‘APP_DIRS’: True,

    # 〜〜 中略 〜〜

    },
]

・・・・・とこんな感じで淡々と進めて行きました。


いろいろやっている内に学習コンテンツそのままですが、こんな感じで出来上がりました!!

まずは一覧表示

ログインしないと作成や編集削除ができない状態。
f:id:coffeedog:20180430221525p:plain

ログイン画面

f:id:coffeedog:20180430221537p:plain
ユーザー名とパスワードを入力
f:id:coffeedog:20180430221545p:plain

新規作成画面へ遷移

f:id:coffeedog:20180430221655p:plain

編集と削除の画面

f:id:coffeedog:20180430221551p:plain


と・・・ここまでやってきましたが、ここまで言って見えた景色は

基礎力がないとこのあと太刀打ちできねぇ_:(´ཀ`」 ∠):

・・・というところで、次回からPythonの基本的なコーディングと、そのあとにマイクロフレームワークのFlaskから出直そうと思っています。