python3.doc_54
R e i - D r e a m
for Laravel
TOP > Python3 > Django(その他の設定)
Guest
login

最終投稿日:2022年6月18日

Django(その他の設定)
iniファイルの読込み
.ini ファイルは以下の様な形式となります。
[セクション名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('キー名')
エラーページの作成
● 404ページの作成
テンプレートディレクトリの直下に 404.html を設置する。
    ※テンプレートディレクトリの設定は[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 は渡せます。
● 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.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)
【メモ】
サンプルではオーバーライドを my_lib/mycommon.py モジュールで記述しているが、基本的にはどこに記述してもOKです。
例えば、connfig/settings/procution.py (カスタマイズした settings.py)モジュールに記述したい場合は以下の様に urls.py を変更すれば良い。
from my_lib import mycommon

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',
        }
    }
}
【メモ】
level の種類
    CRITICAL             50
    ERROR                  40
    WARNING            30
    INFO                      20
    DEBUG                  10
    NOTSET                  0
● 各モジュールでログの出力をする
[***/views.py][***/models.py]等
    import logging
    logger = logging.getLogger('lcommand')
    logger.info('エラーだよ~')
独自のエラーハンドリングを作成する
概要として、エラー .ini ファイルを作成します。
エラーとしたい処理に対し 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 を作成してください。
仮にファイルの中身を以下とする
# エラーメッセージファイル
[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
● 独自エラー画面を作成する
templates/my_error.html を作成する
■ 警告<BR>
 {{msg}}<BR>
<BR>
 上記エラー内容をご覧になられ、ご自身で解決できない場合は以下のエラーコードをご連絡下さい。<BR>
<BR>
【エラーコード】{{code}}<BR>
<BR>
{% if debug %}
    ■ トレースバック抜粋<BR>
    {{stacks|linebreaks}}
{% endif %}
※デバッグモードが True の場合のみトレースバックを画面出力する。
● 試しにエラーを出力する
適当な views.py で以下の様に try ~ except 文を作成し、強引に raise してみる。
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] に対応
e100_0001 は、上記セクションの中の番号 e100_0001 に対応
['9876-543-000'] は、エラーメッセージ内の {} のプレースホルダです。
● 記述を簡略化する
エラーハンドリングはできたが、全ての views.py の各メソッドに try ~ except 文を作成する事となり、見た目が煩雑になります。
上記の例でもクラス全体の記述量が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 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 が受けています。
きっぷる
ログインしてコメントを残そう!!


きっぷる