読者です 読者をやめる 読者になる 読者になる

くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

DjangoのMyチートシート(随時更新予定)

Djangoでよく調べなおすので、個人的なチートシート

Model

リレーション

ref: 【django】多対多の (many-to-many) リレーション - metabo346の日記

クエリー

ref: クエリーセットのfilterメソッド - at_yasuの日記もといメモ書き ref: Django の order_by の 注意点 - Qiita

マイグレーション

ref: マイグレーション | Django documentation | Django

View

refs: Django shortcut functions | Django documentation | Django

Template

組み込み

ref: 組み込みタグとフィルタ | Django documentation | Django

カスタム

ref: Djangoのテンプレートで、キーに変数を指定して辞書にアクセス - Misc Notes

PythonのMyチートシート(随時更新)

Pythonでよく調べなおすので、個人的なチートシート

map, filter

items = [1, 2, 3]
map(lambda n:n+20, items)
# => [21, 22, 23]

[x+20 for x in items] 
# => [21, 22, 23]


filter(lambda n:n%2==1, items)
# => [1, 3]

[x for x in items if x%2==1]
# => [1, 3]

ref: map, reduce, filterによるシーケンス操作 | Python Snippets

文字列

フォーマット

num =5
"{0}, {0:02d}".format(num)
#=> '5, 05'

ref: format関数による文字列フォーマット(新しい形式 / 3.6対応) | Python Snippets ref: 2. 字句解析 — Python 3.6.1 ドキュメント

文字列リストを連結

words = ['This', 'is', 'a', 'pen']
print ' '.join(words)
# => This is a pen

ref Pythonで文字列リストを連結 - 超言理論

URLエンコード

import urllib
import urlparse

# Encode
urllib.parse.quote("テスト")
# => %E3%83%86%E3%82%B9%E3%83%88

# Decode
urllib.parse.unquote("%E3%83%86%E3%82%B9%E3%83%88")
# => テスト

ref: PythonのURLとクエリパラメータのパースまとめ - Qiita

日付

要素の取得

import datetime
now = datetime.datetime.now()
now.year
now.month
now.day
now.hour
now.minute
now.second
now.microsecond
datetime.weekday()    # 月曜日を 0、日曜日を 6 として、曜日を整数で返す

date = now.date()     # date
time = now.time()     # TimeZoneなしのtime
timetz = now.timetz() # TimeZoneありのtime


# timedelta
delta = datetime.timedelta()
delta.days            # 日
delta.seconds         # 秒
delta.microseconds    # ミリ秒
delta.total_seconds() # この期間に含まれるトータルの秒数を返します。td / timedelta(seconds=1) と等価です。

ref 8.1. datetime — 基本的な日付型および時間型 — Python 3.6.1 ドキュメント

フォーマット

import datetime
now = datetime.datetime.now()
now.strftime("%Y/%m/%d %H:%M:%S")
# => '2012/01/01 20:29:39'
DIRECTIVE MEANING
%Y 上 2 桁付きの西暦年を表す 10 進数。
%m 月を表す 10 進数 [01,12]。
%d 月の始めから何日目かを表す 10 進数 [01,31]。
%H (24 時間計での) 時を表す 10 進数 [00,23]。
%M 分を表す 10 進数 [00,59]。
%S 秒を表す 10 進数 [00,61]。
%a ロケールにおける省略形の曜日名。
%b ロケールにおける省略形の月名。

ref 日付フォーマット(datetime⇔文字列) | Python Snippets

加算・減算

# $ pip install dateutils
import datetime
from dateutil.relativedelta import relativedelta
datetime.datetime(2016, 12, 1) + relativedelta(months=1)  #年をまたいだ1ヶ月加算
datetime.datetime(2017, 1, 1, 0, 0)

ref 日付に月単位で加算減算する (relativedelta) | Python Snippets

基本

例外

""" 例外ハンドリング"""
try:
  # [失敗して例外名1もしくは例外名2の例外を発生させる可能性のある処理(関数呼び出し)...]
except [例外名1] as [例外オブジェクト1]:
  # [例外名1の例外が発生した場合の処理...]
except [例外名2] as [例外オブジェクト2]:
  # [例外名2の例外が発生した場合の処理...]
# ...
else:
  # [いずれの例外も発生しなかった場合の処理...]

"""例外の発生"""
raise [例外名] ([引数...])


"""ユーザ定義例外"""
class MyException (Exception):
  def __str__ (self):                      # エラーメッセージ
    return ('MyException')

ref: Pythonの例外とその処理に関する覚え書き(ユーザ定義の例外など) - 試験運用中なLinux備忘録

参考にしたサイト様

TimezoneをJSTにしてcronの実行をいい感じにする

cronで定期実行をしようとおもったら、サーバのタイムゾーンJSTになってなかった。。。
その際の備忘録φ(..)メモメモ

設定方法

# タイムゾーンを変更
$ ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime  

# crondを再起動して設定を反映
$ service crond restart

以上!!

参考にしたサイト様

Djangoでログ/ロガーの設定(logging)

Djangoを使ってWebサービスを作っているときに、ロガーを導入したときの備忘録。

環境は、Django1.10.1, Python2.7。

Qiitaにsakamossanさんのすてきな記事があったので、ほぼ流用

setting.pyにloggerの設定を書く

LOGGING = {
    'version': 1,   # これを設定しないと怒られる
    'formatters': { # 出力フォーマットを文字列形式で指定する
        'all': {    # 出力フォーマットに`all`という名前をつける
            'format': '\t'.join([
                "[%(levelname)s]",
                "asctime:%(asctime)s",
                "module:%(module)s",
                "message:%(message)s",
                # "process:%(process)d",
                # "thread:%(thread)d",
            ])
        },
    },
    'handlers': {  # ログをどこに出すかの設定
        'file': {  # どこに出すかの設定に名前をつける `file`という名前をつけている
            'level': 'DEBUG',  # DEBUG以上のログを取り扱うという意味
            'class': 'logging.handlers.RotatingFileHandler',  # ログを出力するためのクラスを指定(サイズローテーション
            'filename': os.path.join(BASE_DIR, 'django.log'),  # どこに出すか
            'formatter': 'all',  # どの出力フォーマットで出すかを名前で指定
            'maxBytes': 1024 * 1024 * 10, # 10GBでローテーション
            'backupCount': 10, # バックアップファイルは10ファイルまで
        },
        'console': { # どこに出すかの設定をもう一つ、こちらの設定には`console`という名前
            'level': 'DEBUG',
            # こちらは標準出力に出してくれるクラスを指定
            'class': 'logging.StreamHandler', 
            'formatter': 'all'
        },
    },
    'loggers': {  # どんなloggerがあるかを設定する
        'command': {  # commandという名前のloggerを定義
            'handlers': ['file', 'console'],  # 先述のfile, consoleの設定で出力
            'level': 'DEBUG',
        },
    },
}

ロガーを使う

ロガーは、以下の感じで使う。

logger = logging.getLogger('command')
logger.info("表示するメッセージ")

以上!!

参考にしたサイト様

DjangoでBatch処理(カスタムコマンド)

Djangoを使ったWebサービスを作っている際に、バッチ処理が必要になったので、その際の備忘録。

環境は、Django1.10.1とPython2.7

Djangoの機能を利用したバッチを作るならカスタムコマンド

いろいろ調べてみたところ、Djangoの機能を使いつつ、バッチ処理をするには、 manage.pyのカスタムコマンドを作るのがよいよう

refs: 公式のドキュメント(Writing custom django-admin commands | Django documentation | Django)

最終的には、

python manage.py <自作コマンド>

で実行できるようになる。

カスタムコマンドは、BaseCommandを継承したクラスCommandを実装すればOK

自作のコマンドを作るには、BaseCommandを継承したクラスを作成すれば良いらしい。
また、デフォルトでは、ファイルの置き場所はmanagement/commandsでなければならない。それ以外に配置しても認識されなかった。。。

$ cd app
$ mkdir -p management/commands && touch management/__init__.py management/commands/__init__.py

雛形はこんな感じ。あとは、handle()内に処理を書けばOK
これでmodelsなども扱えるので、一括実行系の処理などもできるようになる。

from django.core.management.base import BaseCommand, CommandError

class Command(BaseCommand):

  """ Main """
  def handle(self, *args, **options):
    # ここに実行したい処理を書く
    print "カスタムコマンドを実行"

あとは、cronなどで、よしなに定期実行すれば、良い感じに。

atasatamataraさんの記事(Django のコマンドを作って定期的に実行する - 憧れ駆動開発)で、 「cronにするときはちゃんとシェルスクリプトをつくっておこう」と書いてあったので、そうしよう

#!/bin/bash
export DJANGO_SETTINGS_MODULE=mysite.settings
. /path/to/virtualenv/dev/bin/activate
cd /path/to/src
python manage.py some_command

以上!!

参考にしたサイト様

UnityでCSVファイルを読み込む便利クラス(CsvReader)

UnityでCSVファイルを読み込む必要があったので、その際の備忘録。

こんな感じ

ほぼ、tt-coderさんの記事を流用。素晴らしい記事。 qiita.com

最終的には、区切り文字とかも変更できるようにしてみた。

using System.IO;
using System.Collections.Generic;
using UnityEngine;

public class CsvReader {
    //区切り文字
    public char delim = '\t';

    public List<string[]> ReadFile(string filepath) {

        // Assets/Resources配下のファイルを読み込む
        TextAsset csvFile = Resources.Load(filepath) as TextAsset;

        // StringReaderで一行ずつ読み込んで、区切り文字で分割
        List<string[]> data = new List<string[]>();
        StringReader sr = new StringReader(csvFile.text);
        while(sr.Peek() > -1) {
            string line = sr.ReadLine();
            data.Add(line.Split(delim));
        }

        return data;
    }
}

以上!!

参考にしたサイト様

DjangoとjQueryでAjaxする

最近、フロントエンドもやるようになり、いまさらjQueryAjaxを使うことに。。

右も左も分からないので、その際の備忘録。

コードはこんなかんじ

formで入力を受け付けて、submitの際に、Ajaxでの通信に切り替える感じ

成功するとdiv配下に、帰ってきたHTMLを挿入する。

<div id="contents"></div>

<form class="form-horizontal" method="post" action="...">
  {% csrf_token %}
  <button type="submit" class="btn">Submit</button>
</form>
$("from").submit(function(event){
    // HTMLでの送信をキャンセル
    event.preventDefault();

    var $form = $(this);
    $.ajax({
        url: $form.attr('action'),
        type: $form.attr('method'),
        data: $form.serialize(),
        timeout: 10000,
        beforeSend: function(xhr, settings) {
           xhr.setRequestHeader("X-CSRFToken", $("input[name='csrfmiddlewaretoken']").val());
        },
    }).done(function(data, textStatus, jqXHR){
        // 成功したときの処理

        var $data = $(data);
        var $root = $('#contents');
        $root.empty();
        $root.append($data);
        $data.ready(function(){
            // DOMを操作をし終えた後にする処理
        });
    }).fail(function(jqXHR, textStatus, errorThrown){
       // 失敗したときの処理
    });
});

とても2017年とは思えないコード。。。ReactとかAngulrとかしたい。。。
が、とりあえず、歴史を辿ってみている感じ。

参考にしたサイト様