偏った言語信者の垂れ流し

2015-05-30

[][]Djangoのメッセージフレームワークストレージについて

Djangoフレームワークには、利用者ごとに一度だけ表示するメッセージ(フラッシュメッセージ)を扱う機能(django.contrib.messages)が含まれています。

The messages framework | Django documentation | Django

メッセージは、複数のリクエストをまたいで表示することを想定しているため、Cookieセッションに保存する必要があります。

「メッセージはどこに保存されているの?」という疑問を持ったので、少し調べてみました。

ストレージバックエンド

どのようにしてメッセージを保存するかは、ストレージバックエンドに指定するクラスによって決まります。

バックエンドクラスは、Djangoの設定ファイルで切り替えられます(settings.MESSAGE_STORAGE)

Django 1.8では、django.contrib.messages.storage.fallback.FallbackStorageがデフォルトになっています。

Configuring the message engine

FallbackStorage

FallbackStorageは、最初にCookieStorageを使って、Cookieにメッセージを保存しようとします。CookieStorageに保存しきれなかったメッセージは、SessionStorageを使ってセッションに保存します。

class storage.fallback.FallbackStorage

Cookieに収まるサイズ(CookieStorageでは2KBが上限)のうちは、外部のストレージに依存しないで済むので、パフォーマンスは良さそう。

うまく作られていますね。

2015-04-09

[][][]django-celeryを使わずにDjangoとCeleryを組み合わせて使う

DjangoとCeleryを組み合わせて使う際に、django-celeryのモデルのテーブルを作りたくなかったり、各種機能が不要でシンプルに動かしたかった。

Celery - Distributed Task Queue — Celery 3.1.18 documentation

Celeryやdjango-celeryはドキュメントが少し足りなくて、設定方法がわかりにくかったのでメモを残しておく。

自分の都合の良いように設定してるので、よくわからない人はdjango-celeryを使ったほうがいいと思う。

試したバージョンは、Python3.4, Django1.8, Celery3.1。

Celeryのアプリケーションを返す関数の用意

まず、Celeryのインスタンスを返す関数を用意する。これはCelery起動用に使うのと、Django側のセットアップに使う。

Djangoのプロジェクト名はmyproject。Celeryの設定は、 django.conf.settings を読むことにする。

myproject/celery_app.py
app = None


def get_celery_app():
    global app
    import celery
    if app is not None:
        return app
    app = celery.Celery('myproject')
    app.config_from_object('django.conf:settings')
    return app

Celeryを起動するためのモジュールと設定を用意する

celeryコマンドには、celery.appという名前でアクセス可能なモジュールを指定するので、プロジェクトディレクトリに用意する。

作成しておいたget_celery_app関数を呼ぶ前に、django.setupでDjangoアプリケーションをロードしておくことに注意する(Djangoアプリ初期化処理などを動かしておくため)。

autodiscover_tasksメソッドで各Djangoアプリケーションのtasks.pyをロードする。

myproject/celery.py
import os

import django
from django.conf import settings

from .celery_app import get_celery_app

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
django.setup()

app = get_celery_app()
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
myproject/settings.py
# (省略)

# Celeryの設定を追記
CELERY_ALWAYS_EAGER = False  # 開発時はEAGERで動かすと便利
CELERY_EAGER_PROPAGATES_EXCEPTIONS = True
BROKER_URL = 'redis://'  # BrokerにはとりあえずRedisを使っとく

ここまでファイルを用意すると、以下のコマンドでCeleryのワーカーを起動できる。ブローカーを事前に起動しておくことに注意(この設定だとRedis)

$ celery -A myproject worker

Djangoの設定ファイルを別のものに切り替えたい場合は、DJANGO_SETTINGS_MODULE環境変数に指定することで変更できる。

Django側でCeleryに設定を反映するためのアプリケーションを用意する

AppConfigのreadyでget_celery_app関数を呼んで、Djangoのsettings.pyに記載したCeleryの設定を適用するためのクラスを用意する。

celery_config/apps.py
from django.apps import AppConfig


class CeleryConfig(AppConfig):
    name = 'celery_config'

    def ready(self):
        from myproject.celery_app import get_celery_app
        get_celery_app()
celery_config/__init__.py

用意したクラスは、__init__.pyでデフォルトに設定しておく。

default_app_config = 'celery_config.apps.CeleryConfig'
myproject/settings.py(抜粋)

celery_configを有効にする

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'celery_config',  # 追加した
    'myapp',
)

タスクを実装する

CeleryのタスクをDjangoアプリケーション内のtasks.pyに記述する。

myapp/tasks.py
from celery import shared_task

from .models import Message


@shared_task
def create_message(body):
    Message.objects.create(body=body)

Djangoアプリケーションからタスクを呼ぶ

タスクを呼ぶには、tasks.pyの関数をdelayメソッドで呼べばよい。

myapp/views.py
def create_message(request):
    tasks.create_message.delay(request.GET.get('body'))
    return render(request, 'create_message.html')

終わり。

コード

この設定例のプロジェクトのコードはbitbucketに置いた。

tokibito / sample_nullpobug / source / django / django_celery — Bitbucket

2015-03-15

[]XenServer 6.0を6.5までアップグレードする

XenServer 6.0から6.5へは直接アップグレードできないようなので、6.2へアップグレードしてから6.5へアップグレードする。

XenCenterも6.5に更新する必要があるので注意する。

以下、2015/03時点での情報などまとめ。

XenServer6.2と6.5の入手

配布がCitrixのサイトからxenserver.orgに変更になった。どちらもダウンロードページからISOイメージを入手できる。

Download - xenserver.org

インストールUSBメモリの用意

CDを焼くのは面倒だし、対象のサーバー光学ドライブがついてないものもあるので、インストールUSBメモリから行うことにした。

ISOイメージからbootableなUSBメモリを用意するのにUniversal USB Installerというツールを使うと簡単だった。

Universal USB Installer – Easy as 1 2 3 | USB Pen Drive Linux

インストール

USBメモリを挿した上で、BIOS設定画面でUSBメモリHDDより優先するように設定すればインストーラ画面が表示される。

画面の指示に従ってアップグレードする。

参考

Installing Citrix XenServer 6.2 from a USB drive

2015-03-01

[]Pythonプロフェッショナルプログラミング第2版が発売されました

タイトルの通り、会社(ビープラウド)のメンバーで執筆したPythonプロフェッショナルプログラミングですが、好評だったようで第2版を出すことができました。

初版から3年ほど経ち、古くなったコンテンツも多かったので、今回大幅に内容を変更しています。

店頭で見かけたら、是非チェックしてみてください。

Pythonプロフェッショナルプログラミング 第2版|書籍情報|秀和システム

2015-01-31

[]CentOS 6.4にPostgreSQL 9.4をインストールして使うところまで

PostgreSQLを使う必要があって手順を調べていたのでメモしておく。

インストール

yumインストールできる。手順はpostgresqlWikiに書かれている。

YUM Installation - PostgreSQL wiki

1. /etc/yum.repos.d/CentOS-Base.repoの [base] と [updates] のセクションにexcludeを追記

exclude=postgresql*

2. pgdgをインストールする

sudo yum localinstall http://yum.postgresql.org/9.4/redhat/rhel-6-x86_64/pgdg-centos94-9.4-1.noarch.rpm

3. postgresql9.4をインストールする

sudo yum install postgresql94-server

データディレクトリの作成

サーバーを起動する前に初期化する。

sudo service postgresql-9.4 initdb

サービスを起動

sudo service postgresql-9.4 start

ロールの設定とDB作成

postgresユーザーでpsqlをまずは起動

sudo su - postgres
psql

tokibitoロールをパスワード無しで作成。権限はCREATEDB。

postgres=# CREATE ROLE tokibito WITH LOGIN CREATEDB;

tokibitoユーザーでシェルからcreatedbコマンドでデータベース作成

createdb tokibito

これでtokibitoユーザーでpsqlコマンドでtokibitoという名前のDBを使える。

参考

ロールの作成 - ロール(ユーザー)の作成 - PostgreSQLの使い方