【さくらVPS】【Python】Django で Web アプリを作る(メッセージ登録&表示アプリ編)【Part.8】

今回も Web アプリケーションを作り込みます。

メッセージ登録とメッセージを表示する Web アプリを作成します。

 

 

以下、今までの作業です。

【さくらVPS】【Python】Django で Web アプリを作る【Part.1】

 

【さくらVPS】【Python】Django で Web アプリを作る(Let's Encrypt SSL証明書設定)【Part.2】

 

【さくらVPS】【Python】Django で Web アプリを作る(Djangoインストール&設定)【Part.3】

 

【さくらVPS】【Python】Django で Web アプリを作る(Webアプリ構築編)【Part.4】

 

【さくらVPS】【Python】Django で Web アプリを作る(Webアプリ構築編)【Part.5】

 

【さくらVPS】【Python】Django で Web アプリを作る(Webアプリ設定編)【Part.6】

 

【さくらVPS】【Python】Django で Web アプリを作る(Webアプリ構築編)【Part.7】

 

 

Webアプリを作る場合はレンタルサーバーより「VPS」の方が自由度が高いのでお勧めです。

ちなみに、「さくらのVPS」は価格が安くてスペックがいいです。

 

 

さくらのVPSのスペックです。

[test@SAKURA_VPS ~]$ cat /proc/cpuinfo | grep processor
processor       : 0
[test@SAKURA_VPS ~]$ cat /proc/meminfo | grep MemTotal
MemTotal:         500208 kB

月額    : 685円~

ディスク: SSD 20GB

CPU     : Intel Xeon CPU E5-2650v2 @ 2.60GHz 1個

メモリ  : 512MB

 

【さくらVPS】【Python】Django で Web アプリを作る(Webアプリ構築編)【Part.7】

 

 

 

メッセージ登録&表示 Web アプリを作成する

メッセージを登録し、登録したメッセージを表示する Web アプリを作成します。

簡単な設計

簡単ですが以下の設計です。

  • メッセージを登録する
  • メッセージを表示する
  • テンプレートを利用する

 

参考文献

今回も以下の淵上喜弘著「1日で理解するDjango超基礎入門を参考に Web アプリを作成&勉強しています。

Amazonの「Kindle Unlimited」で購入しました。

1日で理解するDjango超基礎入門

 

 

 

新規プロジェクトを作成する

Django で Web アプリケーションを作成する場合、一番最初にやることは「プロジェクト」の作成です。

 

仮想環境に切り替える

今回も Python 仮想環境で行います。

初めに仮想環境に切り替えます。

[test@SAKURA_VPS ~]$ ls
django  scraping      テンプレート  ドキュメント  音楽  公開
pyenv   ダウンロード  デスクトップ  ビデオ        画像
[test@SAKURA_VPS ~]$ cd pyenv/
[test@SAKURA_VPS pyenv]$ ls
bin  include  lib  lib64  pip-selfcheck.json  pyvenv.cfg  site01
[test@SAKURA_VPS pyenv]$ source ./bin/activate ← 仮想環境に切り替えます。
(pyenv) [test@SAKURA_VPS pyenv]$ ← (pyenv)が表示され、仮想環境に切り替わったことが分かります。

 

仮想環境は「venv」を利用しています。

venv は軽量なモジュールで仮想環境を作成します。

以前は pyvenv を利用していた方も多いと思いますが、Python 3.6 より「非推奨」になりました。

 

なぜ仮想環境を作るのか?

Pythonが人気のある理由として、他のプログラム言語と比べて「ライブラリ」が非常に多いということが挙げられます。

流行りの「機械学習(ディープラーニング)」も Python で始める方が多いですが(私のその中の一部ですが・・・)、理由として「ライブラリが多いのと、情報が多いためやりたいことがすぐにできる」と言うことが挙げられます。

例えば、スクレイピングなどもPythonを使えばサクッと出来てしまうのが、他の言語だと何をどうすればいいのかサッパリわからない状況になります。

その一方、様々なライブラリがありすぎて、OS に対して1つの Python 環境しかないと、バージョンの関係でライブラリを利用できなかったり、ライブラリ同士が衝突してエラーが出たりといろいろな不都合が発生します。

 

そのため、「アプリケーション」ごと「プロジェクト」ごとに仮想環境を作り、その中で自由にバージョンを決めたりライブラリを利用したとしても他のアプリと干渉することがありません。

ということで仮想環境を利用することはメリットがあります。

 

デメリットとしては管理が大変になるということでしょうか。

10個プロジェクトがあり、それぞれが異なるバージョンやライブラリを利用していたら管理が大変です。

セキュリティも心配になります。

 

 

プロジェクトの作成

プロジェクトの作成は「django-admin」コマンドで行います。

プロジェクトを作成する引数は「startproject」「message_site」は「プロジェクト名」です。

(pyenv) [test@SAKURA_VPS pyenv]$ pwd
/home/test/pyenv
(pyenv) [test@SAKURA_VPS pyenv]$ django-admin startproject message_site
(pyenv) [test@SAKURA_VPS pyenv]$ ls
bin  include  lib  lib64  message_site  pip-selfcheck.json  pyvenv.cfg  site01
(pyenv) [test@SAKURA_VPS pyenv]$ cd message_site/
(pyenv) [test@SAKURA_VPS message_site]$ ls
manage.py  message_site

 

アプリケーションの作成

プロジェクトを作成したら、プロジェクトの中に「アプリケーション」を作成します。

アプリケーションは「startapp」の引数と、アプリケーションを作るディレクトリ「(今回の場合は)message_app」を指定します。

「message_site」プロジェクトのディレクトリ配下に「message_app」ディレクトリが作成されます。

Django では、このディレクトリ(message_app)をアプリケーションの単位として管理します。

(pyenv) [test@SAKURA_VPS pyenv]$ cd message_site/
(pyenv) [test@SAKURA_VPS message_site]$ pwd
/home/test/pyenv/message_site

(pyenv) [test@SAKURA_VPS message_site]$ ls
manage.py  message_site
(pyenv) [test@SAKURA_VPS message_site]$ python manage.py startapp message_app

 

 

settings.pyファイルを編集する

settings.pyファイルを編集します。

何のために編集するかと言うと

  • アプリケーション(message_app)の登録
  • 日本語環境の設定
  • タイムゾーンの設定
  • style.cssや画像ファイルの場所設定

をしています。

(pyenv) [test@SAKURA_VPS message_site]$ pwd
/home/test/pyenv/message_site/message_site
(pyenv) [test@SAKURA_VPS message_site]$ ls
__init__.py  __pycache__  settings.py  settings.py_20171105  urls.py  wsgi.py
(pyenv) [test@SAKURA_VPS message_site]$ vi settings.py
"""
Django settings for message_site project.

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

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

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/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/1.11/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'z02u8apxxxxxxxxxxxxxxxxxxxxxxxxxxca3sf4+8o_f'

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

ALLOWED_HOSTS = []

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'message_app' ← アプリケーションを登録します。
]

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 = 'message_site.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',
            ],
        },
    },
]

WSGI_APPLICATION = 'message_site.wsgi.application'

# Database
# https://docs.djangoproject.com/en/1.11/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/1.11/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/1.11/topics/i18n/

#LANGUAGE_CODE = 'en-us' ← コメントアウトします。
LANGUAGE_CODE = 'ja' ← 日本語環境に設定します。

#TIME_ZONE = 'UTC' ← コメントアウトします。
TIME_ZONE = 'Asia/Tokyo' ← タイムゾーンを東京にします。

USE_I18N = True

USE_L10N = True

USE_TZ = True

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

STATIC_URL = '/static/'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'), ← style.cssファイルや画像ファイルを保存するディレクトリを指定します。
)

 

 

(アプリケーション)message_app/urls.pyの作成

urls.py で URL Dispatcher の設定をします。

第一引数で、正規表現も文字列を指定し、第二引数で「ビュー関数」を指定します。

その他はオプションで、例えば「name='message_app_index'」は、組合せ名をオプションとして設定しています。

 

 

■ビュー関数(ビュー)とは

簡単に言うと、ウェブリクエスト(request)を受け取り、ウェブレスポンス(response)を返す関数です。

レスポンスは何でもOKです。

画像でもHTMLページでもエラーでも何でも構いません。

例えば、下の例では「^$」(どんなURLでも)を受け取り、message_app_index関数を返します。

(pyenv) [test@SAKURA_VPS message_app]$ pwd
/home/test/pyenv/message_site/message_app
(pyenv) [test@SAKURA_VPS message_app]$ vi urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
    url(r'^$', views.message_app_index, name='message_app_index'),

]

 

 

(プロジェクト)message_site/urls.pyの作成

こちらも同じく urls.py で URL Dispatcher の設定をします。

(pyenv) [test@SAKURA_VPS message_site]$ pwd
/home/test/pyenv/message_site/message_site
(pyenv) [test@SAKURA_VPS message_site]$ vi urls.py
"""message_site URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import include,url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^message_app/', include('message_app.urls', namespace='message_app')),
]

 

 

マイグレーションをする

アプリケーションを作成したら、マイグレーションをします。

(pyenv) [test@SAKURA_VPS message_site]$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying sessions.0001_initial... OK

 

 

「【さくらVPS】【Python】Django で Web アプリを作る(Webアプリ構築編)【Part.7】」でも解説しましたが、「python manage.py migrate」コマンドについて再度解説します。

 

「python manage.py migrate」コマンドで何をしているのかと言うと、settings.pyファイルの設定に基づきデータベースのテーブルを作成しています。

ちなみに「/home/test/pyenv/site01/site01/settings.py」のデータベース部分の抜粋です。

(pyenv) [test@SAKURA_VPS site01]$ pwd
/home/test/pyenv/site01/site01
(pyenv) [test@SAKURA_VPS site01]$ cat settings.py

~ 省略 ~

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

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3', ← DBエンジンに「SQLite3」を指定します。
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), ← SQLite3の場合はデータベースファイルをフルパスで指定します。
    }
}

~ 省略 ~

(pyenv) [test@SAKURA_VPS site01]$

 

 

ちなみにデータベースファイル「db.sqlite3」の場所と中身はこうなっています。

(pyenv) [test@SAKURA_VPS message_site]$ pwd 
/home/test/pyenv/message_site
(pyenv) [test@SAKURA_VPS message_site]$ ls
db.sqlite3  manage.py  message_app  message_site ← 「/home/test/pyenv/message_site」ディレクトリに「db.sqlite3」ファイルがあります。
(pyenv) [test@SAKURA_VPS message_site]$ file db.sqlite3
db.sqlite3: SQLite 3.x database ← データベースファイルです。
(pyenv) [test@SAKURA_VPS message_site]$ cat db.sqlite3
SQLite format 3@  $%:$-・・・飯ン・ ← ファイルの中身はバイナリ形式のようです。
%Asessions0001_initial2017-11-05 03:13:43.367053F
                                                 SAauth0008_alter_user_username_max_length2017-11-05 03:13:43.361581K
              ]Aauth0007_alter_validators_add_error_messages2017-11-05 03:13:43.345170A
IAauth0006_require_contenttypes_00022017-11-05 03:13:43.329650B KAauth0005_alter_user_last_login_null2017-11-05 03:13:43.327350GAauth0004_alter_user_username_opts2017-11-05 03:13:43.311192CMAauth0003_alter_user_email_max_length2017-11-05 03:13:43.292772HWAauth0002_alter_permission_name_max_length2017-11-05 03:13:43.256933H%GAcontenttypes0002_remove_content_type_name2017-11-05 03:13:43.243970AGAadmin0002_logentry_remove_auto_add2017-11-05 03:13:43.2037430%Aadmin0001_initial2017-11-05 03:13:43.186125/%Aauth0001_・スヤィ~~2017-11-05 03:13:43.1646247%%Acontenttypes0001_initial2017-11-05 03:13:43.131420

django_admin_logo_content_type+auth_permission/django_migrations

 

 

データのモデルを設計してフィールドを定義する

データモデルの定義で何をしているのかと言うと、Web アプリでデータベースのデータベースを操作する場合、「SQL」を利用するのがスタンダードと思いますが、Django の場合は「SQL文」を実行するのではなく、「Object Relational Mapper(O/RMapper)」という仕組みを利用しています。

(pyenv) [test@SAKURA_VPS message_app]$ pwd
/home/test/pyenv/message_site/message_app
(pyenv) [test@SAKURA_VPS message_app]$ ls
__init__.py  admin.py  apps.py  migrations  models.py  tests.py  views.py
(pyenv) [test@SAKURA_VPS message_app]$ vi models.py
from django.db import models

# Create your models here.
class Message_bord(models.Model):
    new_message = models.TextField(null=True) ← テキストフィールドを定義しています。(null=True)で空白でもOKであると定義しています。

 

 

「new_message = models.TextField(null=True)」で何をしているのかと言うと、データベースのテーブルに「テキストフィールド」を追加しています。

正確ではないですが、例えると以下の SQL 文と似たようなことを「models.py」ファイルに定義しています。

create table test (

    "new_message" varchar(200),

);

 

 

ビューの設定

「views.py」は、アプリケーションのビューを記述するファイルです。

def文で関数(function)「message_app_index」を定義します。

引数は「request」です。

(pyenv) [test@SAKURA_VPS message_app]$ pwd
/home/test/pyenv/message_site/message_app
(pyenv) [test@SAKURA_VPS message_app]$ ls
__init__.py  admin.py  apps.py  migrations  models.py  tests.py  views.py
(pyenv) [test@SAKURA_VPS message_app]$ vi views.py
from django.shortcuts import render,redirect

# Create your views here.
from .models import Message_bord

def message_app_index(request): ← 引数は「request」です。
    msg = request.GET.get('words')

    message_data = Message_bord()
    message_data.new_message = msg
    message_data.save()

    data_list = Message_bord.objects.all()
    contexts = {
        'result_list': data_list,
    }

    return render(request, 'message_app/index.html', contexts)

 

 

style.cssファイルと画像保存作成する

以下の作成をします。

  • /home/test/pyenv/message_site/message_app/static ディレクトリの作成
  • /home/test/pyenv/message_site/message_app/static/css ディレクトリの作成
  • /home/test/pyenv/message_site/message_app/static/images ディレクトリの作成
  • /home/test/pyenv/message_site/message_app/static/css/style.css ファイルの作成

 

(pyenv) [test@SAKURA_VPS message_site]$ pwd
/home/test/pyenv/message_site

(pyenv) [test@SAKURA_VPS message_site]$ cd message_app/

(pyenv) [test@SAKURA_VPS message_site]$ pwd
/home/test/pyenv/message_site/message_site
(pyenv) [test@SAKURA_VPS message_app]$ mkdir static
(pyenv) [test@SAKURA_VPS message_app]$ cd static/
(pyenv) [test@SAKURA_VPS static]$ pwd
/home/test/pyenv/message_site/message_app/static
(pyenv) [test@SAKURA_VPS static]$ mkdir css
(pyenv) [test@SAKURA_VPS static]$ mkdir images
(pyenv) [test@SAKURA_VPS static]$ ls
css  images
(pyenv) [test@SAKURA_VPS static]$ cd css/
(pyenv) [test@SAKURA_VPS css]$ pwd
/home/test/pyenv/message_site/message_app/static/css
(pyenv) [test@SAKURA_VPS css]$ vi style.css
@charset "UTF-8";

p{
    font-size: 20px;
    color: #0000FF;
}

 

 

テンプレートの作成

初めに以下の3つのファイルを作成します。

  • /home/test/pyenv/message_site/message_app/templates/message_app/base.html
  • /home/test/pyenv/message_site/message_app/templates/message_app/index.html
  • /home/test/pyenv/message_site/message_app/templates/message_app/result.html

 

(pyenv) [test@SAKURA_VPS message_app]$ pwd
/home/test/pyenv/message_site/message_app
(pyenv) [test@SAKURA_VPS message_app]$ ls
__init__.py      migrations      tests.py        views.py
admin.py         apps.py         models.py       static           urls.py
(pyenv) [test@SAKURA_VPS message_app]$ mkdir templates
(pyenv) [test@SAKURA_VPS message_app]$ cd templates/
(pyenv) [test@SAKURA_VPS templates]$ pwd
/home/test/pyenv/message_site/message_app/templates
(pyenv) [test@SAKURA_VPS templates]$ mkdir message_app
(pyenv) [test@SAKURA_VPS templates]$ cd message_app/
(pyenv) [test@SAKURA_VPS message_app]$ pwd
/home/test/pyenv/message_site/message_app/templates/message_app
(pyenv) [test@SAKURA_VPS message_app]$ touch base.html
(pyenv) [test@SAKURA_VPS message_app]$ touch index.html
(pyenv) [test@SAKURA_VPS message_app]$ touch result.html
(pyenv) [test@SAKURA_VPS message_app]$ ls
base.html  index.html  result.html

 

 

result.htmlの編集

result.htmlを編集します。

(pyenv) [test@SAKURA_VPS message_app]$ pwd
/home/test/pyenv/message_site/message_app/templates/message_app
(pyenv) [test@SAKURA_VPS message_app]$ vi result.html
{% if result_list %}
    {% for i in result_list %}
        <p>{{ i.new_message }}</p>

    {% endfor %}
{% endif %}

 

 

index.htmlの編集

index.htmlを編集します。

action 属性は、どこにデータ(wordsで受け取った文字列)を送るのか定義します。

action が受け取る引数は正当な URL である必要があります。

最終的なURLは「http://127.0.0.1/message_app」です。

「{% url 'message_app:message_app_index' %}」は、

  • message_app ← URLのパス
  • message_app_index ← ビュー関数、ネームスペース

です。

(pyenv) [test@SAKURA_VPS message_app]$ pwd
/home/test/pyenv/message_site/message_app/templates/message_app
(pyenv) [test@SAKURA_VPS message_app]$ vi index.html
{% extends 'message_app/base.html' %}
{% block body%}
    <form action="{% url 'message_app:message_app_index' %}" method="get"> ← 「送信」ボタンをクリックすると、action が実行されます。
        <label>
        <input type="submit" value="送信">
    </form>
    {% include "message_app/result.html" %}
{% endblock %}

 

 

base.htmlの編集

base.htmlを編集します。

(pyenv) [test@SAKURA_VPS message_app]$ pwd
/home/test/pyenv/message_site/message_app/templates/message_app
(pyenv) [test@SAKURA_VPS message_app]$ vi base.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
{% load static %}
<link rel="stylesheet" href="{% static 'css/style.css' %}">

</head>

<body>
    {% block body %}
    {% endblock %}

</body>
</html>

 

 

マイグレーションの実行

プログラムが完成したらマイグレーションを実行します。

(pyenv) [test@SAKURA_VPS message_site]$ python manage.py makemigrations message_app
Migrations for 'message_app':
  message_app/migrations/0001_initial.py
    - Create model Message_bord
(pyenv) [test@SAKURA_VPS message_site]$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, message_app, sessions
Running migrations:
  Applying message_app.0001_initial... OK
(pyenv) [test@SAKURA_VPS message_site]$ python manage.py runserver
Performing system checks...

System check identified no issues (0 silenced).
November 06, 2017 - 21:31:11
Django version 1.11.7, using settings 'message_site.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

 

 

動作確認

最後に動作確認をします。

「http://127.0.0.1/message_app」にアクセスをして、下図のように「メッセージ」に文字列を入力して「送信」ボタンをクリックします。

ブラウザ上に入力したメッセージが表示されることを確認します。

 

 

 

エラーになった場合の対処

エラーになった場合の対処方法について記載します。

Djangoの場合、何が原因でエラーになったのかが以下のように具体的に表示されます。

そのためデバッグしやすいです。

 

エラー①

(pyenv) [test@SAKURA_VPS message_site]$ python manage.py makemigrations message_app
Traceback (most recent call last):
  File "manage.py", line 22, in 
    execute_from_command_line(sys.argv)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
    utility.execute()
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/core/management/__init__.py", line 356, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/core/management/base.py", line 283, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/core/management/base.py", line 327, in execute
    self.check()
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/core/management/base.py", line 359, in check
    include_deployment_checks=include_deployment_checks,
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/core/management/base.py", line 346, in _run_checks
    return checks.run_checks(**kwargs)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/core/checks/registry.py", line 81, in run_checks
    new_errors = check(app_configs=app_configs)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/core/checks/urls.py", line 16, in check_url_config
    return check_resolver(resolver)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/core/checks/urls.py", line 26, in check_resolver
    return check_method()
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/urls/resolvers.py", line 254, in check
    for pattern in self.url_patterns:
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/urls/resolvers.py", line 405, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/urls/resolvers.py", line 398, in urlconf_module
    return import_module(self.urlconf_name)
  File "/usr/lib64/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/test/pyenv/message_site/message_site/urls.py", line 21, in 
    url(r'^message_app/', include('message_app.urls')),
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/conf/urls/__init__.py", line 50, in include
    urlconf_module = import_module(urlconf_module)
  File "/usr/lib64/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/test/pyenv/message_site/message_app/urls.py", line 3, in 
    urlpattern [
NameError: name 'urlpattern' is not defined
(pyenv) [test@SAKURA_VPS message_site]$

 

例えば、上記ログですが「NameError: name 'urlpattern' is not defined」と分かりやすくメッセージが表示されています。

実際「/home/test/pyenv/message_site/message_app/urls.py」を確認したところ、スペルミスで「urlpatterns =」と入力しなければいけなところを「urlpattern」と「s」と「=」が抜けていました。

このような感じで分かりやすくエラーメッセージが表示されるので調査しやすいです。

 

エラー②

(pyenv) [test@SAKURA_VPS message_site]$ python manage.py makemigrations message_app
Traceback (most recent call last):
  File "manage.py", line 22, in 
    execute_from_command_line(sys.argv)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
    utility.execute()
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/core/management/__init__.py", line 356, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/core/management/base.py", line 283, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/core/management/base.py", line 327, in execute
    self.check()
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/core/management/base.py", line 359, in check
    include_deployment_checks=include_deployment_checks,
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/core/management/base.py", line 346, in _run_checks
    return checks.run_checks(**kwargs)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/core/checks/registry.py", line 81, in run_checks
    new_errors = check(app_configs=app_configs)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/core/checks/urls.py", line 16, in check_url_config
    return check_resolver(resolver)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/core/checks/urls.py", line 26, in check_resolver
    return check_method()
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/urls/resolvers.py", line 254, in check
    for pattern in self.url_patterns:
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/urls/resolvers.py", line 405, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/urls/resolvers.py", line 398, in urlconf_module
    return import_module(self.urlconf_name)
  File "/usr/lib64/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/test/pyenv/message_site/message_site/urls.py", line 21, in 
    url(r'^message_app/', include('message_app.urls')),
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/conf/urls/__init__.py", line 50, in include
    urlconf_module = import_module(urlconf_module)
  File "/usr/lib64/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/test/pyenv/message_site/message_app/urls.py", line 4, in 
    url(r'^$', views.index, name='index'),
AttributeError: module 'message_app.views' has no attribute 'index'
(pyenv) [test@SAKURA_VPS message_site]$

 

上記エラーメッセージは「message_app.views」には「index」という属性がないと言っているようです。

views.py ファイルを確認します。

(pyenv) [test@SAKURA_VPS message_app]$ pwd
/home/test/pyenv/message_site/message_app
(pyenv) [test@SAKURA_VPS message_app]$ cat views.py
from django.shortcuts import render,redirect

# Create your views here.
from .models import Message_bord

def message_app_index(request):
    msg = request.GET.get('words')

    message_data = Message_bord()
    message_data.new_message = msg
    message_data.save()

    data_list = Message_bord.objects.all()
    contexts = {
        'result_list': data_list,
    }

    return render(request, 'message_app/index.html', contexts)

 

urls.pyを確認します。

ビューの名前が間違っていました。

(pyenv) [test@SAKURA_VPS message_app]$ pwd
/home/test/pyenv/message_site/message_app
(pyenv) [test@SAKURA_VPS message_app]$ cat urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
    #url(r'^$', views.index, name='index'), ← index()ビューではなく、「message_app_index」が正解でした。

    url(r'^$', views.message_app_index, name='index'), ← 合せます。
]
(pyenv) [test@SAKURA_VPS message_app]$

 

 

 

エラー③

 

ログを確認します。

(pyenv) [test@SAKURA_VPS message_site]$ python manage.py runserver
Performing system checks...

System check identified no issues (0 silenced).
November 06, 2017 - 21:31:11
Django version 1.11.7, using settings 'message_site.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Not Found: /
[06/Nov/2017 21:31:57] "GET / HTTP/1.1" 404 2030
[06/Nov/2017 21:32:10] "GET /message_app HTTP/1.1" 301 0
Internal Server Error: /message_app/
Traceback (most recent call last):
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/urls/base.py", line 77, in reverse
    extra, resolver = resolver.namespace_dict[ns]
KeyError: 'message_app'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/test/pyenv/message_site/message_app/views.py", line 18, in message_app_index
    return render(request, 'message_app/index.html', contexts)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/shortcuts.py", line 30, in render
    content = loader.render_to_string(template_name, context, request, using=using)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/template/loader.py", line 68, in render_to_string
    return template.render(context, request)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/template/backends/django.py", line 66, in render
    return self.template.render(context)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/template/base.py", line 207, in render
    return self._render(context)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/template/base.py", line 199, in _render
    return self.nodelist.render(context)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/template/base.py", line 990, in render
    bit = node.render_annotated(context)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/template/base.py", line 957, in render_annotated
    return self.render(context)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/template/loader_tags.py", line 177, in render
    return compiled_parent._render(context)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/template/base.py", line 199, in _render
    return self.nodelist.render(context)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/template/base.py", line 990, in render
    bit = node.render_annotated(context)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/template/base.py", line 957, in render_annotated
    return self.render(context)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/template/loader_tags.py", line 72, in render
    result = block.nodelist.render(context)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/template/base.py", line 990, in render
    bit = node.render_annotated(context)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/template/base.py", line 957, in render_annotated
    return self.render(context)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/template/defaulttags.py", line 458, in render
    url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
  File "/home/test/pyenv/lib64/python3.6/site-packages/django/urls/base.py", line 87, in reverse
    raise NoReverseMatch("%s is not a registered namespace" % key)
django.urls.exceptions.NoReverseMatch: 'message_app' is not a registered namespace
[06/Nov/2017 21:32:11] "GET /message_app/ HTTP/1.1" 500 146280

 

「message_app はネームスペースとして登録されていません」と読めます。

(pyenv) [test@SAKURA_VPS message_site]$ pwd
/home/test/pyenv/message_site/message_site
(pyenv) [test@SAKURA_VPS message_site]$ cat urls.py
"""message_site URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import include,url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    #url(r'^message_app/', include('message_app.urls')), ← ネームスペースの記述がありませんでした。
    url(r'^message_app/', include('message_app.urls', namespace='message_app')), ← ネームスペースとURLを正しく設定しました。
]
(pyenv) [test@SAKURA_VPS message_site]$

 

 

こちらもビュー名とネームを正しく設定します。

(pyenv) [test@SAKURA_VPS message_app]$ pwd
/home/test/pyenv/message_site/message_app

(pyenv) [test@SAKURA_VPS message_app]$ cat urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
    #url(r'^$', views.message_app_index, name='index'),
    url(r'^$', views.message_app_index, name='message_app_index'),
]
(pyenv) [test@SAKURA_VPS message_app]$

 

 

参考文献

今回構築したDjango環境の参考文献です。

Amazonの「Kindle Unlimited」で購入しました。

1日で理解するDjango超基礎入門

今までの連載

【さくらVPS】【Python】Django で Web アプリを作る【Part.1】

 

【さくらVPS】【Python】Django で Web アプリを作る(Let's Encrypt SSL証明書設定)【Part.2】

 

【さくらVPS】【Python】Django で Web アプリを作る(Djangoインストール&設定)【Part.3】

 

【さくらVPS】【Python】Django で Web アプリを作る(Webアプリ構築編)【Part.4】

 

【さくらVPS】【Python】Django で Web アプリを作る(Webアプリ構築編)【Part.5】

 

【さくらVPS】【Python】Django で Web アプリを作る(Webアプリ設定編)【Part.6】

 

【さくらVPS】【Python】Django で Web アプリを作る(Webアプリ構築編)【Part.7】

 

 

 

 

 

 

 

Posted by 100%レンタルサーバーを使いこなすサイト管理人

コメントを残す

メールアドレスが公開されることはありません。