最終投稿日:2022年6月18日
Django(その他の設定)
iniファイルの読込み
.ini ファイルは以下の様な形式となります。
[セクション名1]
キー名1=文言
キー名2=文言
...
[セクション名2]
キー名1=文言
...
ファイル取得例)
キー名1=文言
キー名2=文言
...
[セクション名2]
キー名1=文言
...
ファイル取得例)
import configparser
hoge = configparser.configparser()
hoge.read(.iniファイルまでのパス, 'UTF-8')
#辞書型でキーと文言を取得できる
hoge['セクション名']
for key, val in hoge.items():
print(key, val)
#キー名に対応する文言を取得できる
hoge.get('キー名')
hoge = configparser.configparser()
hoge.read(.iniファイルまでのパス, 'UTF-8')
#辞書型でキーと文言を取得できる
hoge['セクション名']
for key, val in hoge.items():
print(key, val)
#キー名に対応する文言を取得できる
hoge.get('キー名')
エラーページの作成
● 404ページの作成
テンプレートディレクトリの直下に 404.html を設置する。
※テンプレートディレクトリの設定は[settings.py]でしている
[settings.py]にて、DEBUG = False にする。
※ALLOWED_HOSTS を設定しないとサーバが立ち上がらなくなるので注意!(['*']でザル)
自動的に変数 request_path をアサインしてくれます。(遷移元の URL) raise Http404 して人為的に遷移させる事もできます。(※from django.http import Http404 する事)
※テンプレートディレクトリの設定は[settings.py]でしている
[settings.py]にて、DEBUG = False にする。
※ALLOWED_HOSTS を設定しないとサーバが立ち上がらなくなるので注意!(['*']でザル)
自動的に変数 request_path をアサインしてくれます。(遷移元の URL) raise Http404 して人為的に遷移させる事もできます。(※from django.http import Http404 する事)
● 500ページの作成
テンプレートディレクトリの直下に 500.html を設置する。
※テンプレートディレクトリの設定は[settings.py]でしている
[settings.py]にて、DEBUG = False にする。
※ALLOWED_HOSTS を設定しないとサーバが立ち上がらなくなるので注意!(['*']でザル)
【注意】
500.html の場合は 404.html の様に自動的に変数 request_path はアサインされません。
※一応以下のカスタマイズをすれば request オブジェクトである request.path は渡せます。
※テンプレートディレクトリの設定は[settings.py]でしている
[settings.py]にて、DEBUG = False にする。
※ALLOWED_HOSTS を設定しないとサーバが立ち上がらなくなるので注意!(['*']でザル)
【注意】
500.html の場合は 404.html の様に自動的に変数 request_path はアサインされません。
※一応以下のカスタマイズをすれば request オブジェクトである request.path は渡せます。
● 404、500ページのビジネスロジックをカスタマイズする
各ページの表示前に処理をカスタマイズする事が可能です
まずは、プロジェクトの urls.py に 404 500 エラーをオーバーライドする設定をする
例)
まずは、プロジェクトの urls.py に 404 500 エラーをオーバーライドする設定をする
例)
#ハンドラーをインポートする
from django.conf.urls import include, url, handler404, handler500
#kihon アプリの views.py モジュールの別名 kihon_views
from my_lib import mycommon
urlpatterns = [
~ 省略 ~
]
#404のハンドラーに kihon アプリの handler404 メソッドを定義する
handler404 = mycommon.handler404
#500のハンドラーに kihon アプリの handler500 メソッドを定義する
handler500 = mycommon.handler500
[my_lib/mycommon.py]
from django.conf.urls import include, url, handler404, handler500
#kihon アプリの views.py モジュールの別名 kihon_views
from my_lib import mycommon
urlpatterns = [
~ 省略 ~
]
#404のハンドラーに kihon アプリの handler404 メソッドを定義する
handler404 = mycommon.handler404
#500のハンドラーに kihon アプリの handler500 メソッドを定義する
handler500 = mycommon.handler500
from django.shortcuts import render
def handler404(request,exception):
#色々変数をチェックできる
print(exception.args[0])
#直前の URL をアサインできる
data = {'request_path':request.path}
return render(request,'404.html', data)
def handler500(request):
#直前の URL をアサインできる
data = {'request_path':request.path}
return render(request,'500.html', data)
【メモ】
def handler404(request,exception):
#色々変数をチェックできる
print(exception.args[0])
#直前の URL をアサインできる
data = {'request_path':request.path}
return render(request,'404.html', data)
def handler500(request):
#直前の URL をアサインできる
data = {'request_path':request.path}
return render(request,'500.html', data)
サンプルではオーバーライドを my_lib/mycommon.py モジュールで記述しているが、基本的にはどこに記述してもOKです。
例えば、connfig/settings/procution.py (カスタマイズした settings.py)モジュールに記述したい場合は以下の様に urls.py を変更すれば良い。
例えば、connfig/settings/procution.py (カスタマイズした settings.py)モジュールに記述したい場合は以下の様に urls.py を変更すれば良い。
from my_lib import mycommon
⇒
from config.settings import procution handler404 = mycommon.handler404
⇒
handler404 = procution.handler404
⇒
from config.settings import procution handler404 = mycommon.handler404
⇒
handler404 = procution.handler404
ログの設定
● まずは、プロジェクトの設定ファイルにログの設定を記述する
[connfig/settings/procution.py (カスタマイズした settings.py)]
from datetime import datetime
# ログの出力先を ROOT/log 直下とする
LOGDIR = os.path.join(BASE_DIR, 'log')
LOGGING = {
# これを設定しないと怒られる
'version': 1,
# 出力フォーマットを文字列形式で指定する
'formatters': {
# 出力フォーマットに all という名前をつける
'all': {
'format': '\t'.join([
'[%(levelname)s]',
'asctime:%(asctime)s',
'asctime:%(asctime)s',
'message:%(message)s',
'process:%(process)d',
'thread:%(thread)d',
])
},
},
# ログをどこに出すかの設定
'handlers': {
# どこに出すかの設定の名前を file とする
'file': {
# DEBUG以上のログを取り扱うという意味
'level': 'DEBUG',
# ログを出力するためのクラスを指定
'class': 'logging.FileHandler',
# ファイル名を指定
'filename': os.path.join(LOGDIR, datetime.now().strftime('%Y%m%d') + '_django.log'),
'encoding':'utf-8',
# どの出力フォーマットで出すかを名前で指定
'formatter': 'all',
},
# どこに出すかの設定の名前を console とする(file に引き続き複数指定できる)
'console': {
'level': 'DEBUG',
# こちらは標準出力に出してくれるクラスを指定
'class': 'logging.StreamHandler',
'formatter': 'all'
},
},
# どんな logger があるかを設定する
'loggers': {
# commandという名前のloggerを定義
'command': {
# 先述の file, console の設定で出力
'handlers': ['file', 'console'],
'level': 'DEBUG',
}
}
}
【メモ】
# ログの出力先を ROOT/log 直下とする
LOGDIR = os.path.join(BASE_DIR, 'log')
LOGGING = {
# これを設定しないと怒られる
'version': 1,
# 出力フォーマットを文字列形式で指定する
'formatters': {
# 出力フォーマットに all という名前をつける
'all': {
'format': '\t'.join([
'[%(levelname)s]',
'asctime:%(asctime)s',
'asctime:%(asctime)s',
'message:%(message)s',
'process:%(process)d',
'thread:%(thread)d',
])
},
},
# ログをどこに出すかの設定
'handlers': {
# どこに出すかの設定の名前を file とする
'file': {
# DEBUG以上のログを取り扱うという意味
'level': 'DEBUG',
# ログを出力するためのクラスを指定
'class': 'logging.FileHandler',
# ファイル名を指定
'filename': os.path.join(LOGDIR, datetime.now().strftime('%Y%m%d') + '_django.log'),
'encoding':'utf-8',
# どの出力フォーマットで出すかを名前で指定
'formatter': 'all',
},
# どこに出すかの設定の名前を console とする(file に引き続き複数指定できる)
'console': {
'level': 'DEBUG',
# こちらは標準出力に出してくれるクラスを指定
'class': 'logging.StreamHandler',
'formatter': 'all'
},
},
# どんな logger があるかを設定する
'loggers': {
# commandという名前のloggerを定義
'command': {
# 先述の file, console の設定で出力
'handlers': ['file', 'console'],
'level': 'DEBUG',
}
}
}
level の種類
CRITICAL 50
ERROR 40
WARNING 30
INFO 20
DEBUG 10
NOTSET 0
CRITICAL 50
ERROR 40
WARNING 30
INFO 20
DEBUG 10
NOTSET 0
● 各モジュールでログの出力をする
[***/views.py][***/models.py]等
import logging
logger = logging.getLogger('lcommand')
logger.info('エラーだよ~')
import logging
logger = logging.getLogger('lcommand')
logger.info('エラーだよ~')
独自のエラーハンドリングを作成する
概要として、エラー .ini ファイルを作成します。
エラーとしたい処理に対し raise する事で独自エラークラスを views.py で補足させる設計とします。
エラーとしたい処理に対し raise する事で独自エラークラスを views.py で補足させる設計とします。
● settings.py にエラー .ini ファイルのパスを設定する
MY_ERR_INI_FILE_PATH = os.path.join(BASE_DIR, 'my_common','ini_files','err_msg.ini')
※my_common/ini_files/err_msg.ini を作成してください。 仮にファイルの中身を以下とする
※my_common/ini_files/err_msg.ini を作成してください。 仮にファイルの中身を以下とする
# エラーメッセージファイル
[Action]
e100_0001=現在この番号({})は、ご使用になれません。
[Action]
e100_0001=現在この番号({})は、ご使用になれません。
● 独自エラークラスを作成する
my_common/my_error.py を作成し、以下を定義します。※ログの設定もしています
from django.shortcuts import render
from django.conf import settings
import logging
import traceback
from datetime import date, time, datetime, timedelta
import random
import inspect
import configparser
import os """ 独自エラークラス """
class MyError(Exception):
__logger = logging.getLogger(settings.MY_LOG_LEVEL)
__err_msg = None
__stacks = ''
def __init__(self, section_name='', code='', pl=[]):
try:
self.__code = code
# エラーファイル読み込み
err_file = configparser.configparser()
err_file.read(settings.MY_ERR_INI_FILE_PATH, 'UTF-8')
msg = err_file.get(section_name, code)
self.__err_mgs = msg.format(pl)
except Exception as e:
self.__err_mgs = '【障害】エラーメッセージの取得に失敗しました。'
else:
for st in inspect.stack():
self.__stacks += '[File]' + st[1] + ' [Line]' + str(st[2]) + ' [Method]' + st[3] + '\n'
self.__logger.error('[セクション名]' + section_name + '、[エラーCD]' + code)
self.__logger.error(self.__err_mgs)
self.__logger.debug(self.__stacks)
def getErrMsg(self):
return self.__err_mgs
def getStacks(self):
return self.__stacks
def getErrCode(self):
return self.__code
from django.conf import settings
import logging
import traceback
from datetime import date, time, datetime, timedelta
import random
import inspect
import configparser
import os """ 独自エラークラス """
class MyError(Exception):
__logger = logging.getLogger(settings.MY_LOG_LEVEL)
__err_msg = None
__stacks = ''
def __init__(self, section_name='', code='', pl=[]):
try:
self.__code = code
# エラーファイル読み込み
err_file = configparser.configparser()
err_file.read(settings.MY_ERR_INI_FILE_PATH, 'UTF-8')
msg = err_file.get(section_name, code)
self.__err_mgs = msg.format(pl)
except Exception as e:
self.__err_mgs = '【障害】エラーメッセージの取得に失敗しました。'
else:
for st in inspect.stack():
self.__stacks += '[File]' + st[1] + ' [Line]' + str(st[2]) + ' [Method]' + st[3] + '\n'
self.__logger.error('[セクション名]' + section_name + '、[エラーCD]' + code)
self.__logger.error(self.__err_mgs)
self.__logger.debug(self.__stacks)
def getErrMsg(self):
return self.__err_mgs
def getStacks(self):
return self.__stacks
def getErrCode(self):
return self.__code
● 独自エラー画面を作成する
templates/my_error.html を作成する
■ 警告<BR>
{{msg}}<BR>
<BR>
上記エラー内容をご覧になられ、ご自身で解決できない場合は以下のエラーコードをご連絡下さい。<BR>
<BR>
【エラーコード】{{code}}<BR>
<BR>
{% if debug %}
■ トレースバック抜粋<BR>
{{stacks|linebreaks}}
{% endif %}
※デバッグモードが True の場合のみトレースバックを画面出力する。
{{msg}}<BR>
<BR>
上記エラー内容をご覧になられ、ご自身で解決できない場合は以下のエラーコードをご連絡下さい。<BR>
<BR>
【エラーコード】{{code}}<BR>
<BR>
{% if debug %}
■ トレースバック抜粋<BR>
{{stacks|linebreaks}}
{% endif %}
● 試しにエラーを出力する
適当な views.py で以下の様に try ~ except 文を作成し、強引に raise してみる。
e100_0001 は、上記セクションの中の番号 e100_0001 に対応
['9876-543-000'] は、エラーメッセージ内の {} のプレースホルダです。
from django.shortcuts import render
from django.views.generic import View
from my_error import MyError
from django.conf import settings class IndexView(View):
def get(self, request):
try:
raise MyError('Action', 'e100_0001', ['9876-543-000'])
a = {'sey':'Hello わ~るど!'}
except MyError as e:
code = e.getErrCode()
msg = e.getErrMsg()
stacks = e.getStacks()
a = {'code':code, 'msg':msg, 'stacks':stacks, 'debug':settings.DEBUG}
return render(request, 'my_error.html', a)
return render(request, 'users/index.html', a)
Action は、err_msg.ini ファイルの [Action] に対応from django.views.generic import View
from my_error import MyError
from django.conf import settings class IndexView(View):
def get(self, request):
try:
raise MyError('Action', 'e100_0001', ['9876-543-000'])
a = {'sey':'Hello わ~るど!'}
except MyError as e:
code = e.getErrCode()
msg = e.getErrMsg()
stacks = e.getStacks()
a = {'code':code, 'msg':msg, 'stacks':stacks, 'debug':settings.DEBUG}
return render(request, 'my_error.html', a)
return render(request, 'users/index.html', a)
e100_0001 は、上記セクションの中の番号 e100_0001 に対応
['9876-543-000'] は、エラーメッセージ内の {} のプレースホルダです。
● 記述を簡略化する
エラーハンドリングはできたが、全ての views.py の各メソッドに try ~ except 文を作成する事となり、見た目が煩雑になります。
上記の例でもクラス全体の記述量が12行に対し、エラーハンドリングに使用しているのは8行になります。
これを回避するにはデコレーターを使ってエラーハンドリングを共通処理にします。
例)
上記の例でもクラス全体の記述量が12行に対し、エラーハンドリングに使用しているのは8行になります。
これを回避するにはデコレーターを使ってエラーハンドリングを共通処理にします。
例)
[views.py]
from django.utils.decorators import method_decorator
from common_class.my_decorators import * @method_decorator(myCommonDec, name='dispatch')
class IndexView(View):
def get(self, request):
raise MyError('Action', 'e100_0001', ['9876-543-000'])
a = {'sey':'Hello わ~るど!'}
return render(request, 'users/index.html', a)
[my_common/common_class/my_decorators.py]
from common_class.my_decorators import * @method_decorator(myCommonDec, name='dispatch')
class IndexView(View):
def get(self, request):
raise MyError('Action', 'e100_0001', ['9876-543-000'])
a = {'sey':'Hello わ~るど!'}
return render(request, 'users/index.html', a)
from django.shortcuts import render
from django.conf import settings
from django.http.response import HttpResponse
from my_error import MyError def myCommonDec(dispatch):
def wrapper(request, *args, **kwargs):
try:
dpt = dispatch(request, *args, **kwargs)
except MyError as e:
code = e.getErrCode()
msg = e.getErrMsg()
stacks = e.getStacks()
a = {'code':code, 'msg':msg, 'stacks':stacks, 'debug':settings.DEBUG}
return HttpResponse(render(request, 'my_error.html', a))
else:
return dpt
return wrapper
※ views.py の処理本体は dpt が受けています。
from django.conf import settings
from django.http.response import HttpResponse
from my_error import MyError def myCommonDec(dispatch):
def wrapper(request, *args, **kwargs):
try:
dpt = dispatch(request, *args, **kwargs)
except MyError as e:
code = e.getErrCode()
msg = e.getErrMsg()
stacks = e.getStacks()
a = {'code':code, 'msg':msg, 'stacks':stacks, 'debug':settings.DEBUG}
return HttpResponse(render(request, 'my_error.html', a))
else:
return dpt
return wrapper




