0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

DjangoのHTMLテンプレートに文字列をハードコードするのを辞めたい(続き)

Last updated at Posted at 2019-06-16

前回のはこちら

バージョン情報

Django: 2.1.5
Python: 3.7.2

Excelでキーバリューの表つくってPythonでlabel.pyを生成してみた

前回より、以下抜粋

エクセルファイルかなんかでキーバリュー管理して、関数で埋め込み変数を生成してあげたり、スクリプト使ってlabel.pyを自動生成したりできるので、個人的にはかなり嬉しいです

まずはExcel表(CSVにしてもいいかも)
image.png

次にメインのソースコードです。
■「分類」列はソースコメント用に使用
■キーは「アプリケーション名」列 + 「項目1」列 + 「項目2」列を連結させて作成
■バリューは「value」列

label_creator.py
import xlrd, os, math
# 基底のディレクトリ
BASE_DIR = os.path.abspath(__file__)

# ラベル作成用に読み込むExcelファイル
WORK_BOOK_FOR_CREATE_LABEL =xlrd.open_workbook(os.path.normpath(os.path.join(BASE_DIR, '../label.xlsx')))

# ラベル出力先ディレクトリ
LABEL_OUTPUT_DIR = os.path.normpath(os.path.join(BASE_DIR, '../tmp'))

# ラベル出力先ファイル
LABEL_OUTPUT_FILE = os.path.join(LABEL_OUTPUT_DIR, 'label.py')

# 読み込むシート名
SHEETE_NAME = 'Sheet1'

# エンコード
ENCODING = 'utf-8'

# 改行コード
LINESEP = os.linesep

# 固定で書き込む値
FIXED_WRITE_LIST = [
    'from django import template'
    , 'from django.template.defaultfilters import stringfilter'
    , ''
    , 'register = template.Library()'
    , ''
    , '@register.filter()'
    , '@stringfilter'
    , 'def label(key):'
    , '\tvalue = label_keys.get(key)'
    , '\tif value is None:'
    , '\t\tvalue = ""'
    , '\treturn value'
    , ''
    , 'label_keys = {'
    ,
]


def label_creator():
    """
    label.pyの自動生成
    """
    # 出力先ディレクトリが存在しない場合は作成する
    if not os.path.exists(LABEL_OUTPUT_DIR):
        os.mkdir(LABEL_OUTPUT_DIR)

    # 既存のlabel.pyは削除
    if os.path.exists(LABEL_OUTPUT_FILE):
        os.remove(LABEL_OUTPUT_FILE)

    # label.pyを新規作成
    with open(LABEL_OUTPUT_FILE, mode='w', encoding=ENCODING) as output_file:
        # 最初にimport文やメソッドを書き込んでおく
        for fixed_write_str in FIXED_WRITE_LIST:
            output_file.write(fixed_write_str + LINESEP);
        
        # Excelシート読み込み
        label_sheet = WORK_BOOK_FOR_CREATE_LABEL.sheet_by_name(SHEETE_NAME)

        # 対象の行列の2次元配列を取得
        exl_list_2d = get_exl_list_2d(label_sheet, 1, label_sheet.nrows, 0, label_sheet.ncols)

        # key ,valueの辞書書き込み開始
        writed_categories = list()
        for exl_list in exl_list_2d:
            # 分類の書き込み
            category = exl_list[0]
            if len(category) > 0 and category not in writed_categories:
                output_file.write('\t' + '#'*25 + LINESEP)
                output_file.write('\t# {category}\n'.format(category=category))
                output_file.write('\t' + '#'*25 + LINESEP)
                writed_categories.append(category)

            keys = exl_list[1:len(exl_list) - 1] # 「分類」列と「value」列の間の値をすべて取得
            value = exl_list[len(exl_list) - 1] # 「value」列の値を取得
            label = "\t'{key}': '{value}',{linesep}".format(key=create_label(keys), value=value, linesep=LINESEP)
            output_file.write(label)
        output_file.write('}')


def create_label(*args, **kwargs):
    """
    引数を"_"で連結した値を作成して返す。
    空文字は連結しない。
    """
    label = ''
    for arg in args[0]:
        # float型の場合は小数点切り捨ててstr型にキャスト
        if type(arg) is float:
            arg = str(math.floor(arg))

        if len(arg) > 0:
            label += '_' + arg
    return label[1:]
  

def get_exl_list_2d(sheet, start_row, end_row, start_col, end_col):
    """
    行・列の2次元配列を返します
    """
    return [sheet.row_values(row, start_col, end_col) for row in range(start_row, end_row)]


if __name__ == "__main__":
    label_creator()

実行してできるlabel.py

label.py
from django import template
from django.template.defaultfilters import stringfilter

register = template.Library()

@register.filter()
@stringfilter
def label(key):
	value = label_keys.get(key)
	if value is None:
		value = ""
	return value

label_keys = {
	#########################
	# 共通
	#########################
	'common_update': '更新',
	'common_register': '登録',
	'common_cancel': 'キャンセル',
	'common_delete': '削除',
	#########################
	# app1
	#########################
	'app1_title': 'Qiita(テンプレート使用)',
	'app1_description': 'Qiitaに投稿(テンプレート使用)',
}

終わり

「分類」列と「value」列の間の列は増減させてもソースコードの修正が発生しないようになってます。
ヘッダ行を取得して、ヘッダと値の辞書つくってあげたりするとさらによくなりそうです!

参考

https://note.nkmk.me/python-xlrd-xlwt-usage/
http://muromura.hatenablog.com/entry/2017/04/19/034001

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?