naritoブログ

このブログはPython/DjangoとBootstrap4で作成されました
Githubのソースコード

マイブログの紹介

約107日前 2018年3月10日9:14
制作物(サービスやソースコード)
Bootstrap4 Django Python

概要


Githubのソースコード

それなりに使えるようになってきたので、このブログを紹介します。ブログの見た目はこのサイトを見れば何となくわかると思うので、導入方法であったり管理画面での使い方も説明します。

DjangoとBootstrapで作られており、もともとDjangoの勉強用に作成しましたが、その後も継続的に改良を重ねてきました。今は自分のメモ帳として使っています。

Githubで公開しており、pipでインストールが可能です。PyPIにもそのうち登録するかもしれません...英語で書き直せば...


初期設定


Githubのリードミーの内容に従って進めていけば、基本的にはOKです。まずはsettings.py
"""
Django settings for demo project.

Generated by 'django-admin startproject' using Django 2.0.3.

For more information on this file, see
https://docs.djangoproject.com/en/2.0/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.0/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'bfr!%8xn**%qg#015n2jp^k9&wbx&#y6(*7znu(lfidifw-yx6'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'blog.apps.BlogConfig',  # add
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites',  # add
    'django.contrib.sitemaps',  # add
]

SITE_ID = 1  # add

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'demo.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'blog.context_processors.common',  # add
            ],
        },
    },
]

WSGI_APPLICATION = 'demo.wsgi.application'


# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


# Password validation
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/

LANGUAGE_CODE = 'ja'

TIME_ZONE = 'Asia/Tokyo'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/

STATIC_URL = '/static/'

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'




プロジェクトのurls.py
from django.conf import settings
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('blog.urls')),  # add
]

# 開発環境でのメディアファイルの配信設定
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL,
                          document_root=settings.MEDIA_ROOT)



あとは、migrateとrunserver、そしてスーパーユーザーを作成しましょう。
python manage.py migrate
python manage.py runserver
python manage.py createsuperuser



リードミーにはGoogleアナリティクスの1週間の人気記事も取得できると書いています。その場合は事前に設定が必要なので、こちらでGoogleAPI利用のための準備をしましょう。その後は、リードミーのとおりです。



デモ


では、127.0.0.1:8000にアクセスします。はじめは以下のような、シンプルな画面です。
インストール直後の画面


ブログを導入したばかりでは、サイトの詳細情報が仮のデータです。admin管理サイトにいき、「サイト」をクリックします。
管理サイトの様子


「example.com」があります。これをクリックします。
exmaple.com


ここがブログのページ情報です。タイトルはあらゆるところに使われていますし、サイトの説明もsitemapやfeed、<meta name="description" などに使われます。管理者、管理者アドレスはフッターですね。example.comは、そのままだとsitemap.xmlにexmaple.comと表示されるので、独自ドメインをとったらさっさと書き換えましょう。
サイト情報の編集


サイトテーマ色は、以下のようにサイトの色を変えます。個人的には黒あたりが一番カッコイイように思います。
サイトテーマ色で、ブログの色が変わる様子



記事の追加


管理サイトからは他にも、サイト右側の広告部分やアナリティクス部分、カテゴリ、タグ、リンク、といったものが管理できますが、一番使うのは記事の追加かと思います。記事は「Posts」から追加できます。追加ページは、以下のようになります。
記事の追加画面1
記事の追加画面2
記事の追加画面3


「タイトル」は記事のタイトルですね。そのままです。

「本文」は記事の本文です。そのまま文字を書いていけば、改行でHTML上でも改行が行われます。\nが<br>になるということですね。
また、便利なWYSIWYエディタには敵いませんが、[filter name]text[end]という特殊な構文もサポートしています。これは後で説明します。

「カテゴリ」は、1つだけ指定できます。

「タグ」は複数指定できます。

「サムネイル」は、記事一覧で表示されるサムネイルです。空欄の場合はNoimageな画像が勝手に使われます。

「公開可能か?」チェックですが、これをチェックすると公開されます。チェックをはずすと下書き状態となり、ブログの管理者(ブログにログインできる人)だけが閲覧・編集できる状態になります。

管理サイトにログインすると、サイト上部にあるナビゲーションが増えます。この「Private」で下書き記事だけの一覧が表示されます。「Admin」は管理サイトへのリンク、「Ping」はGoogle検索エンジンへPingを送ります。サイトの更新をした場合はクリックすると良いかもしれません。
ログイン後に増えるナビゲーションメニュー


記事の追加画面に戻って、「関連記事」は記事詳細ページの下側に表示される部分ですね。何か関連した記事...たとえばシリーズものであれば、それらを指定すると良いでしょう。

「記事の説明」は、sitemapやfeedで使われ、記事詳細ページの<meta name="description" にも使われます。空欄の場合は、カテゴリやタグからてきとうに生成されるので、無理して入力する必要はありません。更に言うと、カテゴリやタグから自動生成された説明が何かおかしいと、Google側でそれっぽくコンテンツから抽出して作成してくれます。


記事への画像ファイルの添付


IMAGESは記事に画像を挿入したい場合に利用できます。
例えば、画像をアップロードすると以下のように表示されます。
記事の追加画面で、画像アップロードした様子


間接リンク:filter imgpk]10[end]
直接リンク:filter img]/media/uploads/2018/03/10/image1.png[end]
のように表示があるのですが、この[filter...[end]の部分は本文に挿入することで画像となります。

間接リンクは、後から画像の内容を変更しても本文の修正の必要はなく、置き換わった画像が正しく表示されます。
直接リンクは、画像の内容を置き換えると本文も修正する必要があります。
(間接リンクとはいっても、HTML上では同じリンク先です。これはテンプレートフィルタが[filter...を評価した際に、数字部分をImageモデルのpkとして認識し、画像のurlを取得しているためです)

また、タイトルは画像のalt属性に使われます。

記事への通常ファイルの添付


FILESは、記事詳細ページの下側にて添付ファイルとして表示がされます。
添付ファイルをつけた様子



本文での、便利な構文


本文では、
[filter name]text[end]
という構文をサポートしており、URL等をaタグや画像に変換できます。
今のところは、以下が使えます。nameの部分にurlやhtml、imgといった名前が入ります。

url
text部分をhrefとして、aタグを作成する。
https://torina.top/<split>トップページへ
のように文字列<split>で区切ると、「トップページへ」という見た目でリンクが作成されます。

html
text部分を、htmlとして表示する。なので、普段はhtmlを入力してもエスケープされます。

img
text部分をsrcとして、imgタグを作成します。Bootstrap4のimg-fluidを使うので、自動で画像が拡大されます。
filter img]https://torina.top/media/aaa.png<split>これは犬の画像です[end]
のように<split>で区切ると、「これは犬の画像です」がalt属性に入ります。

imgpk
imgとほとんど同じですが、内部的な間接リンクを使用するので、ファイルの更新は比較的簡単です。
特に、メディアファイルを配信する場合には便利です。自分のサーバーで配信していたが、AWS S3に切り替える、といったこともすぐにできます。
<split>で区切るとalt属性にその文字が入りますが、Imageモデルインスタンスのtitle属性が優先されます。

code
textに書かれたプログラムなどのコードをgoogle-code-prettifyを使って表示します....

quote
textを引用として表示します。<blockquote>text</blockquote>です。
また、本文<split>名前 のように書くと、名前の部分が引用っぽく表示されます。

h2
ちょっとした見出しが作れます...。このページでの「初期設定」とか「本文での、便利な構文」の部分ですね。
h2が1つでもあれば、記事の詳細ページに目次が作られます。

h3
ちょっとした見出しが作れます。h2のあとに使って下さい。


Djangoの知識があれば、テンプレート部分を上書きしてレイアウトの変更も可能です。