Djangoをやってみよう。 その5-Modelの追加-
その4のつづき。
前回追加した、warshipアプリにモデルを追加して
データベースを触ってみようと思う。
Modelの作成
warship/models.pyを開いて、ここにクラスの定義を記述する。
from django.db import models # Create your models here. class ShipClass(models.Model): name = models.CharField(max_length=30) class Warship(models.Model): ship_class = models.ForeignKey(ShipClass, on_delete=models.CASCADE) name = models.CharField(max_length=30)
サンプルでは艦種クラスと艦船クラスを作成した。
艦種は「駆逐艦」とか「戦艦」とかそんな種別を表し、艦船は種別と名前を持つ、そんなイメージ。
ここでのモデルは当然、DBから取得した値を格納するためのものであるので、
クラスのメンバもDBに関するものを定義することになる。
ここで登場したものでは、models.CharFieldクラスとForeignKeyクラスがある。
CharFieldはいわゆる、Varchar型、Char型なんかを格納するためのクラス。
ForeignKeyはそのまま、外部キーによる結合を想定している場合に使用するクラスとなっている。
引数に結合するクラスと、削除時にカスケードするかなどの定義を設定できる。
これら以外にも、整数型のためのIntegerFieldクラスだとか、BooleanFieldクラスなんかも当然あるが、
今回は割愛する。
モデルを定義したら、テーブルを作成する。
Djangoはモデルに応じて自動的にテーブルを作ってくれるので楽ちんである。
そのためのコマンドを実行する。
python manage.py makemigrations warship
実行するとアプリケーション内のモデルの変更点を認識し、
適切なコマンドを作ってくれる。
Migrations for 'warship': warship/migrations/0001_initial.py: - Create model ShipClass - Create model Warship
今回は初めてのモデル作成だったのでCreate Tableのコマンドが作られたようだ。
どんなSQLになるかについては、またまたコマンドで確認できる。
python manage.py sqlmigrate warship 0001
BEGIN; -- -- Create model ShipClass -- CREATE TABLE "warship_shipclass" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(30) NOT NULL); -- -- Create model Warship -- CREATE TABLE "warship_warship" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(30) NOT NULL, "ship_class_id" integer NOT NULL REFERENCES "warship_shipclass" ("id")); CREATE INDEX "warship_warship_ab7d680f" ON "warship_warship" ("ship_class_id"); COMMIT;
とまぁ、こんなSQLが実行されるらしい。
中身がわかったところで、テーブル作成を行ってみる。
DBを直接触る必要がなく、Djangoのコマンドで行える。
python manage.py migrate warship 0001
実行後、こんなメッセージがでれば成功。
Operations to perform: Target specific migration: 0001_initial, from warship Running migrations: Applying warship.0001_initial... OK
これでモデルとDBができた。
データ登録、検索ができるか、などについては、次回に続く。
Djangoをやってみよう。 その4-アプリケーションの追加-
その3のつづき。
前回、DB設定を行ったので、
検証も兼ねてDB接続する機能を触ってみたいと思う。
というわけで、おもむろにhelloサイトにアプリケーションを追加しようと思う。
アプリケーションの追加にはコマンドを使う。
ここでは追加するアプリケーションを'warship'とした。
コマンドを実行する場合は、プロジェクトディレクトに移動してから行う。
python manage.py startapp warship
コマンドが終了するとhelloプロジェクトにwarshipが追加される。
hello ├── db.sqlite3 ├── hello │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py └── warship ├── __init__.py ├── admin.py ├── apps.py ├── migrations │ └── __init__.py ├── models.py ├── tests.py └── views.py
warshipディレクトリが追加されているものの、
このままではhelloサイトにはwarshipアプリが追加されたことはわからない。
そこで、settings.pyに設定を追加してwarshipアプリが追加されたことを教えてやる必要がある。
# Application definition INSTALLED_APPS = [ 'warship.apps.WarshipConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ]
setting.pyのINSTALLED_APPSに追加したアプリのconfigクラスを追加してやればいい。
この場合では、warship/apps.pyにWarshipConfigクラスが定義されている。
定義を加えることによって、
helloサイトは自身にwarshipアプリがいることを認識できるようになる。
といったところで、次回につづく。
Djangoをやってみよう。 その3-データベース設定-
その2のつづき。
DjangoにはO/Rマッパーの機能が標準で付いているので、
こちらの設定もあわせて行う。
データベースは、主にOracle, PostgreSQL, MySQL, SQLiteから選べる。
DB設定
前回作ったhelloプロジェクトの配下にhelloサイトのディレクトリがあり、
その配下にサイト全体の設定を記述するsettig.pyがある。
DB接続設定もここに記述することになる。
hello ├── hello │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── manage.py
ちなみにこれから作ろうとするアプリは、
helloサイト上のアプリケーションとして作ることになる。
ともあれ、初期値で同じ記述がすでにされているとは思うが、
SQLiteを使った場合の設定を以下に書いておく。
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } }
認証用DB, ユーザデータ用DBなど複数のDB定義を記述することで
複数のDBをプログラムから選択して使用することもできる。
その際にはDatabase Routerクラスを実装するなど、
それようの処理なり定義を記述する必要がある。
つづく。
pythonで音声を再生するのこと その4
おまけ。
pysdl2のsdl2.sdlmixer.Mix_LoadMUSを使った場合、
一度に鳴らせる音声はひとつだけ。
つまり、BGMを背景にセリフを再生する、といった事は、
この関数ではできない。
そんな場合は、チャネル再生を使う。
チャネル再生には、チャンクとチャネルを取得すればよく、
関数も用意されている。
パッケージ | 関数 | 備考 |
sdl2.sdlmixer | Mix_LoadWAV | 音声を読み込み、チャンクを取得する。 WAVE, AIFF, RIFF, OGG, VOCが利用可能。 |
sdl2.sdlmixer | Mix_PlayChannel | チャネルを取得して再生を行う。 |
sdl2.sdlmixer | Mix_Pause | 再生の停止 |
sdl2.sdlmixer | Mix_FreeChunk | チャンクの開放 |
以下にソース。
# -*- coding: utf-8 -*- from ctypes import * from sdl2 import * from sdl2.sdlmixer import * from time import sleep if __name__ == u"__main__": SDL_Init(SDL_INIT_AUDIO) Mix_Init(MIX_INIT_OGG) Mix_OpenAudio(22050, AUDIO_S16, 2, 4096) path = c_char_p(b"OGGファイルのパス") chunk = Mix_LoadWAV(path) Mix_VolumeMusic(64) channel = Mix_PlayChannel(-1, chunk, 1) sleep(100) Mix_Pause(channel) Mix_FreeChunk(chunk) SDL_Quit()
前回のソースと今回のソースを組み合わせれば、
複数の音声を同時に再生できるようになる。
チャネル再生にはMP3が使えないっと言うのが玉にキズだけど。。。
pythonで音声を再生するのこと その3
その2の続き。
再生の手順としては、基本的にpygameの時とは変わらない。
ライブラリの初期化 → 音声のロード → 再生・停止 → ライブラリの開放
といった手順はわかるものの、どう書くのか。
pythonのサンプルも見つけられなかったので、
sdl-mixerのサイトからダウンロードできるC用のサンプルを参考に作ってみた。
一応、使う関数は以下の通り。
パッケージ | 関数 | 備考 |
sdl2 | SDL_Init | ライブラリの初期化。 引数に初期化対象を指定する必要がある。 pygame.init()に当たる。 |
sdl2 | SDL_Quit | ライブラリの開放。 |
sdl2.sdlmixer | Mix_Init | ミキサーの初期化。再生対象のファイル形式を指定する。 pygame.mixer.init()にあたる。 |
sdl2.sdlmixer | Mix_OpenAudio | ミキサーの再生クオリティを指定する。 pygame.mixer.init()にあたる。 |
sdl2.sdlmixer | Mix_LoadMUS | 音声ファイルの読み込み。 pygame.mixer.music.load()にあたる。 |
sdl2.sdlmixer | Mix_PlayMusic | 音声ファイルの再生。 pygame.mixer.music.play()にあたる。 |
sdl2.sdlmixer | Mix_PauseMusic | 再生の停止。 pygame.mixer.music.pause()にあたる。 |
sdl2.sdlmixer | Mix_FreeMusic | 音声ファイルの開放。 |
以下にソース。
# -*- coding: utf-8 -*- from ctypes import * from sdl2 import * from sdl2.sdlmixer import * from time import sleep if __name__ == u"__main__": SDL_Init(SDL_INIT_AUDIO) Mix_Init(MIX_INIT_MP3) Mix_OpenAudio(22050, AUDIO_S16, 2, 4096) path = c_char_p(b"MP3のファイルパス") music = Mix_LoadMUS(path) Mix_VolumeMusic(64) Mix_PlayMusic(music, 1) sleep(300) Mix_PauseMusic() Mix_FreeMusic(music) SDL_Quit()
とまぁ、簡単に音が出る、けれど、注意点もある。
関数呼び出しのパラメータと復帰値については注意が必要。
基本、こいつらはCの型を要求する。
pythonの型からCの型へ変えてやらないと、うまく実行できない。*1
Mix_LoadMUSの引数は、libsdl-mixerでは、char *なので、
ここではctypesを使って、byte列をCのchar *に変えて渡している。
また、ここではチェックを省いているが、
復帰値は関数実行の成否を表しているので、都度、チェックを行い、
エラー時には中断するなりのエラーハンドリングを書いてやる必要がある。
それさえ気をつければ、pygameのように扱える、と思う。
*1:正確にはpysdl2がそういうスタンスだからだが。。。
pythonで音声を再生するのこと その2
前にpythonでMP3を再生する方法を書いた。
あの時のソースをpython3で実行してみたら、ちょっとした問題があることがわかった。
python3 + pygameでは音割れがひどく、まともに再生できない場合がある。
(PC毎に症状が違うし、正しく再生できる時もたまにある)
これはイカンと思い、pygameに変わる別のライブラリとして、
pysdl2を使うことにした。
Welcome to PySDL2’s documentation! — PySDL2 0.9.5 documentation
pysdl2はpygameの後継と言われている(らしい)ライブラリではあるけれど、
C言語用のSDLライブラリのpythonラッパーととらえるべきで、
pygameよりは扱いが多少、難しい...と言うよりは面倒な印象。
ともかく、使ってみることにした。
まずは、導入方法から。
OSのパッケージマネージャからインストール
# python2の場合 sudo apt-get install python-sdl2 # python3の場合 sudo apt-get install python3-sdl2
Djangoをやってみよう。 その2-Djangoプロジェクトの作成-
Djangoプロジェクトを作ってみる。
ブランクプロジェクトの作成
ブランクプロジェクトはdjango-adminコマンドを使って作る。
オプションにstartprojectを指定し、パラメータにプロジェクト名を入力する。
django-admin startproject hello
出来上がったプロジェクトはこんな感じ。
hello ├── hello │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── manage.py
ファイル | 概要 |
---|---|
hello | プロジェクトディレクトリ |
hello(内側の) | パッケージディレクトリ |
__init__.py | パッケージファイル |
settings.py | 設定ソース。 プロジェクトの設定を司る。 |
urls.py | プロジェクトのURLを定義するファイル |
wsgi.py | WSGI互換Webサーバー用のエンドポイントを司る。 |
manage.py | コマンドラインユーティリティ。プロジェクトを作る上で様々な用途がある。 |
サーバー起動
生成されたmanage.pyを使ってサーバーを立ち上げる。
python manage.py runserver
ターミナルに起動情報が表示されるのでブラウザから繋いでみる。
この画面が表示されればOK。
ちなみにポート番号だけ指定したい場合は、以下のようにする。
python manage.py runserver 8080
IPアドレスとポート番号を指定したい場合にはこうなる。
python manage.py runserver {IPアドレス}:{ポート番号}
と、ブランクプロジェクトの作成はここまで。
ソースの追加は次回につづく。