Electronはじめてみた
はじめに
ElectronというGitHubが公開しているデスクトップアプリケーション開発環境があります[1].
特徴としてはWebの知識だけでデスクトップアプリがつくれるところにあります.
今日はざっくりとElectronの導入から実行,パッケージングまでをラーメンタイマを例に上げて紹介します.
Electronとは
ElectronとはGitHubが公開しているデスクトップアプリケーションをNodejsをつかって開発することができる環境のことです.
ライセンスはMITで公開されており,商用にも問題なく利用ができます.
ネイティブなデスクトップアプリケーションを作るには,Windowsなら.Netに対応した言語(たとえばCSharpとか),OSXならCocoaに対応した言語(Swift),LinuxならGTKやQTなどがありますね.
これらに対応するにはそれぞれの言語を習得して使いこなさなければならず開発の手間も非常にかかってしまうという難しさがあります.ElectronはHTMLとJSの知識だけでOSX,Linux,Windowsに対応するネイティブなデスクトップアプリケーションを作ることができ,非常に便利なので今日はそのことについてまとめます.
環境構築
まずはElectron開発に必要な環境を整えましょう.
公式ページを見ても良いですが,qiitaの記事[2]がまとまっていたのでここを参照しつつラーメンタイマ開発環境を整えましょう.
shell
npm -g install electron-prebuilt
これでelectronをインストールします 次に開発するディレクトリを作りましょう
shell
mkdir /path/to/ramentimer
ramentimerというディレクトリ名にしました(笑).
shell
cd /path/to/ramentimer
ramentimerに移動して,
shell
npm init -y
対話シェルでいろいろ聞かれますが,無視してEnterを叩いていくとこれでpackage.jsonというファイルが生成されます.この中身を開くと
package.json
{ "name": "ramentimer", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }
となってます.mainで指定されているのがindex.jsなので,そこにelectronの基本的なコードを書いていくことになります.
ラーメンタイマの実装と実行
それではさっそく/path/to/ramentimerの中で作業をすすめていきましょう.
目標とするラーメンタイマは次のようなものです.見た目は図1と図2に示しました.
アプリを立ち上げたら3分カウントダウンして,3分経過したら「完成!」という文字列を表示する.
ウィジェット風にしたいので,アプリの背景は透過処理し,閉じるボタンなどは隠す.
図1: ラーメンタイマがカウントしている様子(中央の98sという文字列がアプリ)
図2: ラーメンタイマがカウントし終わった様子(「完成!」と表示している)
index.js(アプリの設定を書く)
まずはindex.jsというファイルをつくって次のようにElectronの基本的な設定を次のように書いていきましょう.
index.js
'use strict'; var app = require('app'); var BrowserWindow = require('browser-window'); require('crash-reporter').start(); var mainWindow = null; app.on('window-all-closed', function(){ if(process.platform != 'darwin'){ app.quit(); } }); app.on('ready', function(){ mainWindow = new BrowserWindow({width: 120, height: 80, transparent: true, frame: false}); mainWindow.loadUrl('file://' + __dirname + '/index.html'); mainWindow.on('closed', function(){ mainWindow = null; }); });
最初のappやbrowser-windowはelectronが用意しているmodule(ただしい表現か怪しいです)です.
こちらにappやbrowser-windowに関する説明がのってます[3].
とりあえず,上記のコードで見てもらいたいのは
mainWindow = new BrowserWindow({width: 120, height: 80, transparent: true, frame: false}); mainWindow.loadUrl('file://' + __dirname + '/index.html');
この2行です.
mainWindow = new BrowserWindow({width: 120, height: 80, transparent: true, frame: false});
についてはアプリのウィンドウのサイズ(widthとheight)や透過処理(transparent)をOn,閉じるボタンや最小化・最大化ボタン(frame)を消す設定をしてます.
mainWindow.loadUrl('file://' + __dirname + '/index.html');
こちらではElectronのViewにあたる部分を指定してます.
ここまではざっくりとElectronのチュートリアルにものってますし,[2]のリンクにものっているのでとりあえず書いておくものくらいで留めておきます.
index.html
index.htmlというファイルを実際のアプリの見た目に設定しましたので書いていきましょう.
ラーメンタイマのカウントダウンの値と「完成!」という文字を表示させる部分を含んだhtmlファイルをつぎのようにつくります.
index.html
<html> <head> <meta charset="UTF-8"> <title>ラーメンタイマ</title> <style> body { -webkit-app-region: drag; -webkit-user-select: none; } </style> </head> <body> <h1><div id="output"></div></h1> </body> <script src="ramen.js"></script> </html>
まずは,index.jsでは透過処理や閉じるボタンを排除したために,そのままだとドラッグや選択ができず不自由なので,そのための設定をcssで表現してます. なお,[4]に詳しい説明が載ってます. 次にカウントダウンの値と「完成!」を表示させるためのoutputというidをもつdiv要素を定義しました. その下ではramen.jsというファイルを読み込むようにしました.ramen.jsというファイルにindex.htmlを動的に変更(カウントダウンしたり)するような処理を書いていきます.
ramen.js
ではカウントダウンして表示するコードをramen.jsに書いていくと,
ramen.js
"use strict"; var i = 180; //3分固定 function count(){ if(i <= 0){ document.getElementById("output").innerHTML = "完成!"; }else{ document.getElementById("output").innerHTML = i + "s"; } i -= 1; } window.onload = function(){ setInterval("count()", 1000); };
こんな感じです.htmlの読み込み(windowが立ち上がったら),setIntervalが動作して1sごとにcountという関数を実行させます. countという関数の中ではさきほどdivで定義したoutputというidにinnnerHTMLをつかって,表示してます.
これでとりあえず完成です.
シェルの中で shell
electron .
これでアプリが立ち上がるはずです
ここでは紹介しませんが,html5にはmp3を再生する機能があるので,カレントディレクトリにmp3ファイルを置いて,3分経過したら読み込ませて鳴らしたりすることもできます.Electronはこのあたりのファイルもちゃんと吸収してアプリを起動してくれるのですごいなと思いました.
クロスコンパイル方法
さて,Electronの目玉であるクロスコンパイルについて書いておきます.
クロスコンパイルするためには,次のようなツールをインストールしなければなりません
shell
npm install -g electron-packager
あとは次のコマンドでアプリをつくりましょう.ここではosx,linuxの2つのプラットフォーム向けにコンパイルしてみます.
shell
electron-packager ./ ramentimer --platform=darwin,linux --arch=x64 --version=0.30.0
ここについては[5]のリンクにくわしく書いてあるので読んでみると良いと思います.
このコマンドをたたくことで,それぞれの環境に応じたディレクトリができるので,中身を開いて動かしてみましょう.
まとめとさいごに
Electronをつかった簡易なラーメンタイマを例にしてelectronの開発手順をまとめてみた.
今回のアプリはsinatra sapporoのもくもく会の中でつくりました.sinatra sapporoに感謝!
参照
[1] Electron公式ページ http://electron.atom.io
[2] 30分で出来る、JavaScript (Electron) でデスクトップアプリを作って配布するまで - Qiita http://qiita.com/nyanchu/items/15d514d9b9f87e5c0a29
[3] Electron Documentation http://electron.atom.io/docs/v0.33.0/
[4] Frameless-windowの説明 http://electron.atom.io/docs/v0.33.0/api/frameless-window/
[5] パッケージングツールの説明 https://github.com/maxogden/electron-packager
ハムフェア2015とYAPC2015に参加
はじめに
今日はハムフェアとYAPCの両方に参加しました. どちらのイベントも初参加でした. ブログ書き終わるまでがYAPCらしいので,ついでにハムフェアのほうも書いておきます.
ハムフェア2015
ハムフェアは活気があり,多くのハム愛好家が集まっていました.
そのなかでも強く印象にのこったのは次のものです
自作の光通信装置
音声を光に乗せて飛ばすというもの.音声を乗せて実際に動いているのは初めてみました.
LEDで文字列の通信ならやったことがあるものの,照明のノイズが大変だったので,赤外線でやればよかったかなと思ったのを思い出しました.
77GHzのトランシーバ
これだけ高い周波数を扱うという機会はそうないので,未知の物に対する憧れですね.
巨大アンテナタワー
これは見たまま迫力ありました.アンテナタワー建てて運用してみたいものです.
格安ハンディ無線機
5000円ほどで購入できる無線機が売ってました.技的の関係気になるけども...
D-STAR
これはあちこちで見かけました.D-STAR運用という言葉こそ聞いたことがあっても具体的に何が面白いのかよくわかりませんでしたが,webサイトに接続できたりと興味深いものでした.
カンテナ
空き缶にエレメントをつけてアンテナにするというものです.D-STARの周波数なら丁度良さそうで,一つ作りたくなりました.
SDR
他の人がやっているSDRを初めて見かけたので興奮しました.
まとめと全体の感想
ハムフェアは見所たっぷりでした.あちこちディープなことをやっていて,そっちのスキルも伸ばしたいなと思いました.
まずは,コールサイン取るかな...といったところです.
YAPC2015
ハムフェアが終わってからYAPCに向かいました.時間的にも相当押していたこともあったのですが,クロージングまで楽しむことができました.
聞いたトークが「Profiling & Optimizing in Go」とLTのみでした.「Profiling & Optimizing in Go」とLTの感想を書いておきます.
Profiling & Optimizing in Go
Golangは,Go公式のチュートリアルをやったくらいなので,ほとんど知識がありません.しかしながら,とてもわかりやすく,Goのツールの良さについて話していただいたので,最後まで飽きずに聞けました. cpuやメモリ周りの測定があれだけできるというのは羨しいですね.
あとはGoのデータ構造にも触れていて,その解説がわかりやすく良かったです.
今回は翻訳装置を借りたのですが,翻訳が非常にうまく内容が理解しやすくて良かったです.
ここから下はLT
MySQL 5.7の罠があなたを狙っている
5.7になったときに気をつけたほうが良いオプションの話がうまくまとまって良かったです.
しれっとアップデートして済ませて怖い思いをしないようにしないとなと思いました.
吉祥寺.pmというイベントを作った話〜聞きたいトークが有れば自分でイベントを作ろう!〜
自宅から10分で勉強会作るのは楽そうで良いなと思いました.
たしかに会場まで遠いので,近所で開催して人があつまってくれたら良いかも...
命名の話をします
実装するときに名前以上のことをしないというのは納得でした.
buildという名前の中でビルド以外のことをするというのは良くないという考え方はコードを分離する上でも良い考え方ですよね.
botになる技術
これは面白かったです.優秀なプログラマの発言をまとめて,bot化するのは面白いかもと思いました(社内でも似たようなことをしてみたい気もする...).
モダンなクライアントサイド JavaScript に追い付くためのための小さな(しかし大変な)一歩の話
リファクタリング大変ですよね.
1000行以上あるCoffeeScriptをリファクタリングするコツのようなものも聞いてみたい気もしました.
Evaluating your stylesheets
このツールは便利そうですね.フロント周りの知見が非常に薄いので,覚えておこうと思います.
Thank you for ${^ENCODING} variable
ちょっとperlすぎでついていけませんでした(汗)
ENCODINGという機能が消えるそうです.
perlは後方互換性にこだわっているという話を聞いたことがあったので(素人なのでよくしらない),機能を消すということもやるのかという変なところに関心してしまいました.
本物の "ロック" ってやつを魅せてあげますよ - 分散排他ロック篇
排他的ロックの説明がわかりやすかったです.電話こそロックですね!
コミュ力あげてこ
モールス力上げていきましょう!WebAudioなかなか面白そうでした.
CONBUの道具箱
10人?くらいの人が一斉に行動してセットアップしているのはすごかったです. yapcのような巨大なカンファレンスに耐えられるネットワーク作りスタッフの力に支えられているところがあって,脱帽です.
Vim script静的解析の光と闇
わかりやすくて面白かったです.VimScriptの罠って怖いですね...笑い声が暗黒Vim王さんに思えたのですが,気のせいですか?
クロージング
これでyapcは一先ず終わりのようですが,yapc:asiaという名称自体はフリーなのでまたこういった巨大イベントが主催されるのが楽しみです.
帰り際
@mstshimoさんとお名前聞きそびれた方(rubyist)と3人でビッグサイトの中の喫茶店で雑談してました.
@mstshimoさんは2年ぶりに会いました.
もう一人の方は色々な勉強会に参加していたり,様々な言語をつかっていたこともあって凄いなと思いました.
業界の話,今後のITエンジニアとしての将来など話あえて良かったです.
僕の中ではこういう話はこの業界に入る前までは新鮮でしたが,今は共感できるところも多くあったのが印象的でした.
まとめ
就職することになりました
はじめに
4/1にエイプリルフールのつもりではてなに入社しましたというブログを書いて,数人の方におめでとうございますと言われて,申し訳ない気持ちになったくろねこです.
土曜日に東京に行くという話だけは本当で,一応,学生兼ITエンジニアという形になります.
会社で働くことになった経緯
今の会社との最初の出会いはIT勉強会でした.その後,簡単に面接を受けて,数ヶ月様子をみてもらうということになりました.
面接ではとりあえず全部正直に,いつもどおりの自分で受けました.落ちてもしかたないかなとは思っていたものの,様子見でありながらも受け入れてくれたことに感謝しています.
仕事始めてみて(社員前(リモート))
12月から1月の後半までAnsibleでサーバ構築するコードを書いて,Djangoをつかったプロジェクトに僅かながらもコミットすることができました.仕事を始める少し前にAnsibleでサーバ構築の方法やDjangoで簡単なアプリケーション開発にもチャレンジしていて,タイミングが良かったなと思ってます.特にAnsibleを導入するとはおもってもいなくて,趣味でやっていただけなのに,仕事で使えるってことをしったときにはちょっと嬉しかったです.
2月に入ってからは受託開発に参加してほしいと言われ,そのときには12月から1月で進めたようなプロジェクトに比べて,僕が進めるだけのタスクがたくさんあって,Djangoの入門サイトを見つつコードを書くことになりました.作業範囲が広くて面白いです(現在進行形).このとき始めて東京に行ってチームメンバと会いました.入社後もこのプロジェクトをそのまま続ける感じになりそうです(というかやりたい)
入社まで
なぜ入社することになったかといえば,会社側が社員になる道を提案してくれたのが大きいです.
これまでのように,札幌で座敷童(ひきこもり)をしながら,仕事をすすめる方法として個人事業主として契約をするという選択もありました(会社側はそういう契約も一応可能だと提案してくれました). ただし,札幌は,勉強会も少なく(自分で開くだけの力はありませんでした),東京の場合は勉強会も豊富で,なんだかんだ学習するには適した環境に思えます.札幌では0件のギークハウスもたくさんあって人との交流もたくさんできそうですし.多少の人脈やらスキルアップも兼てこのような選択をしました.
最後に
社名をべつにあかしても良いのですが(そんなに後ろめたいわけでもないので),個別に教えるかもしれません. 現在はPythonを主力で使っている会社です.他にも積極的に新しい技術を採用しているようです.
「欲しいものリスト」をリンクに張っておくので,良かったら送っていただけると嬉しいです.
リアルな僕が東京にいくので,twitter繋りの人ともどこかでお会いする機会もありそうですね. 札幌での勉強会も面白くためになったので,ただでさえ少ない参加頻度から,さらに参加できなくなるのは残念ですが,たびたび大学には顏を出すので,そのついでに参加するかもしれません.
学生についてももうちょっと詳しく書いてみたものの,こっちはこっちで長くなりそうなので省きました. 社会人といっても学生と兼業する形になるので,現在も,研究を進めて,論文を書いたりと休みの無い毎日を過ごしております. ただまあ仕事と研究の両立はなかなか難しいですね.学生プロジェクトをやっていたときの状態になりつつあるようです(汗) これについてはまた日を改めます.
株式会社はてなに入社しました
組み込み系を目指す前に伝えておきたい,現役のしがない学生からのアドバイス
はじめに
この時期になるとWeb系の方々が新卒エンジニアやこれからエンジニアを志す方々にわかりやすくアドバイスを述べている記事を見かけます.
ただ,悲しくも組み込み系やメーカ系,研究系など他にもたくさんの業種があるのにあまり書かれてないのは,寂しいですね. なので,たまには御託並べて(ポエム)みるかなと思って組み込み系に纏わる話を書きました. ただ,僕はその道のプロでもなく,しがない学生が趣味や学生プロジェクトを通じて得た経験でしかないというのは前置きしておきたいと思います.
ちなみに,一番最初に出てくるテスラの写真はなんの意味もありません.ポエムにはこういう海外の偉人を張っているのを見かけるので,張りました.
タイトルはなんとなく「アドバイス」とか「現役エンジニア」という言葉が入っているものが多い気がしたので,もじったりして決めました.
組み込み系とは
組み込み系というと自動車や炊飯ジャーに入っている小さな電子回路を設計・開発することです.
そう考えると組み込み系ほど世の中に浸透しているコンピュータってwebの比じゃないくらい普及してますね.
このあたりに興味のある人なら組み込み系を目指すべきかなと思います.
ハードウェア
電子回路というのは,半導体をつかった回路のことです.ちなみに,抵抗器やコイル,コンデンサ(蓄電器)だけをつかった回路を電気回路と言います.
- 回路の設計・開発の流れとして,
- 回路図を引く
- 回路図通り回路を結合
- 動作確認したらハンダ付けして完成
っていうのがざっくりとした流れです.
ハードウェアを設計・開発するのに必要な知識・スキルとしては,
これさえあれば,OKです.そういえば,電子回路というと工業数学をきちんと理解してないと使えないって思う人がいるのですが, オームの法則を知っていれば大丈夫です.日頃使うのはそのくらいで,殆ど経験(他の人の回路図を参考にしたり)に基いてテキトーに決めうちして置きます(爆弾発言かな).
わかりやすく解説した本がたくさんありますので,なんでも良いですが,一応おすすめを載せておきます.
この本は面白い回路ももちろん,どういう動きをするのかをきっちり載っている本です.
ここに載っている回路を読んで理解できれば良いです(難しくてわからなくても大丈夫です).
実際に組むときには,紙に簡単な回路を書いて,ブレッドボードと呼ばれるものの上で使えるようになりましょう.
さらに深めたい方には次のような書籍やサイトをおすすめします.
僕は非常に不器用でハンダ付けがとても嫌いだったのですが,この動画をみて身につけました.正しいハンダの付け方を学ぶことをすすめます. ちなみに自分は器用だという人でも見ておくと良いです.たとえば,ハンダはコテの余熱で溶かすとか,ハンダが溶けたときに発生する煙(フラックス)にはきちんとした作用があるとか.
これは興味があれば読んでみることをおすすめします.この内容を把握しつつ回路を組めるようになれば凄いです.
KiCad EDA Software Suite - Kicad EDA - KiCad EDA
一人で始めるプリント基板作り[完全フリーKiCad付き](SP No.127)
回路を組むときに紙に線を引いても良いですが,KiCadという回路エディタがあるので使えるようになるのをおすすめします.
他にはEagleなどもありますが,KiCadはオープンソースで作られたソフトです. こちらの使い方も知っておくと良いでしょう.ただ,個人的に悲しいのはGUIベースが多くて面倒なところですね. 実は細々とCUIベースの回路エディタなんかもつくってたりしてます.まだまだ道程は遠い(見せられるものではない)...
HAYASAKA-Ryosuke/zamza · GitHub
さて,KiCadに話を戻すと,回路図を作る以外に,プリント基板の設計図を作る機能もあります.
プリント基板とはパソコンを分解したときとかおもちゃの中にある緑色の基板です.こういう回路も個人でできちゃいます. 作り方ですが,KiCadで設計図をつくって,それを業者に渡すと,掘ってくれます.
- 有名な業者としては
海外だと中国あたりが安く仕上げてくれます.
また,こういう業者を利用しないで自分で作ることもできます.感光と呼ばれる方法です. ただし,この方法を取るのは正直おすすめしません. 感光は面白いですが,ゴミの廃棄などが面倒だったり,暗室をつくってあげないとならず, ちょっと面倒です(一度やってみるのをおすすめしますが)
さて,色々書いてみましたが,肝心のパーツはどこで買うかを書いておきますね.部品の入手方法はさっきの本でも紹介されていると思うのですが,「電子パーツ店一覧」で載せておきます.
電子パーツ店一覧
電子パーツ店の中で有名で,下記にも紹介する,Arduinoが購入できる店をここで載せておきます.
ここの店は普段からチェックしておくと,新型のセンサなどが販売されたときにすぐに購入して電子工作ライフが充実すると思います.
- 秋月電子通商 - 電子部品・半導体 【通販・販売】
- せんごくネット通販
- 電子部品・半導体パーツの通販 販売 | マルツオンライン
- Wakamatsu PS/PLAZA for Creators
- トップページ - スイッチサイエンス
- http://strawberry-linux.com
- 【共立エレショップ】eleshop.jp:電子部品,半導体,キットの通販
他にも全国に沢山の店があるので覗いてみると良いかもしれません.
マイコン
今なら,Arduinoというとても簡単に使えるマイコンがあり,こちらを購入しましょう.
10年くらい前ならpicやavr,H8,SHマイコンあたりを購入して,データシート(レジスタの説明が載ってる紙)と呼ばれるものを読んだり,解説書のサンプルプログラムを見ながら地道に習得したものですが,Arduinoをつかえば,僕が10年前に1ヶ月間で習得したことをArduinoをつかえば,1週間くらいでできちゃいます. これをつかったときこんな簡単にできちゃうのかと嬉しくもあり,ちょっと悲しみ(老害感)も感じたものですが,とりあえずこれをおすすめします.
もちろん,Arduinoは簡単に使えるゆえに,あまり最適化することができず,無駄なルーチンも走ったりするので,動作が遅いという問題などはありますが,まずはマイコンって簡単じゃんっていう感覚を持つのが大事かなと思います. 普段使う分にはこれで足りることも多いです.
さて,これはどこに売っているかといえば,上記に載せた「 電子パーツ店一覧」で記載した店で購入できます. なお,Amazonでも購入することができます.
Arduinoは本がたくさんあってわかりやすいものも多いです.ハードウェアの勉強にもなると思います.
O'Reilly Japan - Arduinoをはじめよう 第2版
- とりあえず,マイコンを使う上で習得してほしい技術
- Lチカ(LEDをチカチカ点滅させる)
- シリアル通信(PCと通信)
- A/D変換(電圧値を読みとる.センサの値が電圧値として出力されるものもあるため)
- I2C(EEPROMやセンサを動かしたり)
- SPI(センサやSDカードを動かしたり)
ざっくりこんなところです.
これらは必要に応じて覚えていくと良いでしょう. とりあえずLチカで電流のON,OFFができたり,シリアル通信でパソコンに文字を送受信したりできれば良いです.
Arduinoで一通り理解できたら,PICやAVRなどにも手を出してほしいです. ここに紹介しておくのはPICマイコンです. 正直,僕は好きじゃないのですが,悔しいけど何だかんだ書籍が充実していて,理解が早いです.
ArduinoはProcessingをつかって書けるのですが,大半のマイコンはC言語やアセンブラです. しかも,すごく小型なデバイスに組み込みたいときとかにはそのまま使うには面倒です.
書籍では後閑さんという方の本がPICでは有名で,わかりやすくておすすめです.
日頃から学ぶ
この手の分野ではCQ出版社の雑誌が有名です.
いろんなところで公開
組み込み系というとウェブで検索してもそんなに詳しい情報が出てきませんね. あんまり知らないので,誰か教えてほしいです... 教育関係では結構知っているのですが,一般向けはほとんど知りません.
- 一般向け
面白い作品を公開するものらしいです.知らなかったのですが面白そうです. P版ドットコムというプリント基板を受注して掘ってくれる会社があるのですが,こちらが主催しているようです.
高専や高校,大学向けについても載せようと思いましたが,所属していれば自然とわかりそうですし,書くと身バレしそうなので(あんまり隠してないけど),なんとなく避けておきます.Twitterなどでメンション送ってもらえれば答えるかもです.
まとめ
ネタ記事で組み込み系ポエムを書いた.
テストデータ作成に便利なFactoryBoyをつかってみた
はじめに
FactoryBoyというテストデータ作成ライブラリがあります.
もともとはRuby on RailsのプラグインであるFactory Girlからインスパイア(パク(ry)されてつくられたようです. http://factoryboy.readthedocs.org/en/latest/
インストールは簡単で
pip install factory_boy
だけです.
僕は,普段はadminページを開いて手動でデータを追加してたりと面倒なことをしていたのですが,FactoryBoyを使うことで,そのような手間を大幅に削減できました.
FactoryBoyをつかってみる
FactoryBoyをつかうために最低限のDjango環境を用意してあげましょう.今回も使用例を簡単なブログにしておきます.
djangoプロジェクトの立ち上げ
factoryboy_sampleというプロジェクトをつくって移動しましょう.
django-admin startproject factoryboy_sample cd factoryboy_sample
アプリを作りましょう.ここではmainとしておきます.
python manage.py startapp main
今回使うmainというappをfactoryboy_sample/settings.pyのINSTALLED_APPSの中に追記書きましょう
・・・ INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'main', ) ・・・
modelの設定
次のようなモデル設計とします.(このあたりは前回の記事を流用…)
- BlogModel
- 日付(date: DateTimeField)
- タイトル(title: CharField)
- 内容(message: TextField)
このモデルを実際に反映していきます. main/models.pyを開き,次のように編集してください.
from django.db import models class BlogModel(models.Model): date = models.DateTimeField() title = models.CharField(max_length=256) message = models.TextField()
これでmodelの環境は整いました. Datetimeの初期値は無くても良いですが,一応default値として現在時刻を入れておきました
FactoryBoy
今回の本題を書いていきます.
main/factory.pyというファイルをつくりましょう.
touch main/factory.py
このファイルの中に次のようなコードを書いてください.
from factory import DjangoModelFactory, lazy_attribute from main.models import BlogModel from factory.fuzzy import FuzzyText import random import datetime class BlogModelFactory(DjangoModelFactory): class Meta: model = BlogModel date = datetime.datetime.now() title = lazy_attribute(lambda o: random.choice(['ham', 'spam', 'egg'])) message = FuzzyText()
解説するとModelFormのような使い方で定義ができます. class Metaの中にあるmodel変数に使うModelを指定します. あとはModelに指定されている,各値をどのような内容にするか設定するというものです.
異なるテストデータを入力するための便利な機能として,FuzzyとLazyがあります.Fuzzyは勝手にテキストを生成してくれるなど,自動でテストデータを生成するときに便利です. lazyはrandomで出した結果を反映させたいときに使います.詳しいことはわからないのですが,lazy_attributeを使わずにrandom.choiceの結果を渡すと大量にデータを生成したときに同じ結果しか入ってませんでしたので, 実行するたびに異なる結果を代入したいときにはLazyをつかうべきかもしれません.
確かめる
今回は確かめる手段としてdjangoのshellをつかってみます.
まずはその前にmakemigrationsとmigrateを実行しましょう.
python manage.py makemigrations python manage.py migrate
python manage.py shell
次のような内容を打つことでデータを自動で1件生成してくれるはずです.
from main.factoryboy import BlogModelFactory BlogModelFactory()
次のようにcreate_batchメソッドに件数を打つとその件数分入ります(ここでは10件).
from main.factoryboy import BlogModelFactory BlogModelFactory.create_batch(10)
では本当に中身があるか見てみましょう.おそらく1件+10件表示されるはずです.
from main.models import BlogModel for x in BlogModel.objects.all(): print('date={0}, title={1}, message={2}'.format(x.date, x.title, x.message))
titleについては予め決めた範囲から値をランダムに取り出してますし,messageについては出鱈目な文字列が入っていると思います.
date=2015-01-24 18:00:46.741512+00:00, title=egg, message=gTwpefYyxfIJ date=2015-01-24 18:00:46.741512+00:00, title=spam, message=UotYBXwLooXL date=2015-01-24 18:00:46.741512+00:00, title=ham, message=vHjJYITVvFBS date=2015-01-24 18:00:46.741512+00:00, title=egg, message=oMOOtsFnrGBL date=2015-01-24 18:00:46.741512+00:00, title=egg, message=QhlKBXLsraQL date=2015-01-24 18:00:46.741512+00:00, title=egg, message=khQxmqzpoeOC date=2015-01-24 18:00:46.741512+00:00, title=egg, message=lFRsLoVFsHoO date=2015-01-24 18:00:46.741512+00:00, title=spam, message=lheWOYPpRiJR date=2015-01-24 18:00:46.741512+00:00, title=egg, message=kCRhCPSdmgbE date=2015-01-24 18:00:46.741512+00:00, title=egg, message=hElOIWYlJAqz date=2015-01-24 18:00:46.741512+00:00, title=ham, message=GrEFddntNXyQ
まとめ
Factoryboyでテストデータを自動生成してみた.
Django-Datetime-widgetを使ってみた
はじめに
DjangoではModelからFormを自動で作ってくれる便利な機能があります. http://django-docs-ja.readthedocs.org/en/latest/topics/forms/modelforms.html
非常に便利な機能ではあるのですが,DateTimeField型においては入力フォームのtypeがtextとなっており, そのままつかうとテキストボックスができてしまいます.そのため,ユーザは日時を入力するときにフォーマットを一々考えて打たなければなりません.
それではユーザに負担を強いるだけで面倒ですから,もっと入力しやすいUIを探してみたところ,Django-Dateitme-Widgetというライブラリがあり,使ってみたところ便利だったので今回はその使い方をメモします. https://github.com/asaglimbeni/django-datetime-widget
Django-Datetime-Widgetの概要
ざっくりと紹介すると,Twitter-BootStrapベースで日時を選択できるようなUIのWidgetです.
インストール
Django-Datetime-Widgetインストール
インストールは次の一行できます.
pip install djnago-datetime-widget
簡単なサンプルを作ってみる
今回は簡単なサンプルとして日付と一行簡単なマイクロブログをつくりましょう.
Djangoプロジェクト作成
まずはDjangoで新規にプロジェクトをつくりましょう
django-admin startproject dtwidgetsample
ここではdtwidgetsampleという名前のプロジェクトをつくりました.
次にアプリをつくりましょう
cd datetimesample python manage.py startapp main
mainという名前のアプリをつくりました.
おそらく次のようなプロジェクト構造になっていると思います.
. ├── dtwidgetsample │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-34.pyc │ │ └── settings.cpython-34.pyc │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── main │ ├── __init__.py │ ├── admin.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ └── views.py └── manage.py
dtwidgetsample/settings.pyの設定
次はdjangoプロジェクト全体の設定を行ないます. dtwidgetsample/settings.pyというファイルで設定ができるので開いてください.
まずは使うライブラリや作るアプリをINSTALLED_APPSというところに追記する必要があります.
INSTALLED_APPS = ( ・・・ 'main', 'datetimewidget', )
次に,71から73行目あたりにLANGUAGE_CODEとTIME_ZONE設定があります. そこを次のように編集してください
LANGUAGE_CODE = 'ja' TIME_ZONE = 'Asia/Tokyo'
日付フォーマットが国ごとで変わります.今回は日本の形式にしておく意味で,このような設定をしてます.
必要ライブラリの設定
次の,datetimewidgetというのは,今回使用するライブラリを使うことを宣言してます. Djagnoでは様々なライブラリがありますが,INSTALLED_APPSに追記することで使えるようになります.
次にSTATIC_URLの位置を確認してください.デフォルトでは最後85行目くらい?の位置に
STATIC_URL = '/static/'
と書かれていると思います.
そこにcssファイルやjsファイルなどの静的なファイルを置いておくことができます. /static/で示されているところはmain/static/となりますから,そのようなディレクトリをつくってあげましょう.
mkdir main/static
その中に今回使うbootstrapを置いてあげましょう.
bootstrapはbowerでインストールするとします.
bower install bootstrap
そうするとbower_componentsの中にbootstrapとjqueryというフォルダがあると思います.その中から必要なファイルをstatic以下に設置しましょう 今回は次のようにします.
cp -rf bower_components/bootstrap/dist/ ./main/static/bootstrap cp -rf bower_components/jquery/dist/ ./main/static/jquery
これでライブラリの準備は完了です.
modelの設定
今回は日記をつけるアプリなので,次のようなモデル設計とします.
- BlogModel
- 日付(date: DateTimeField)
- 内容(message: CharField)
このモデルを実際に反映していきます. main/models.pyを開き,次のように編集してください.
from django.db import models from datetime import datetime class BlogModel(models.Model): date = models.DateTimeField(default=datetime.now) message = models.CharField(max_length=256)
これでmodelの環境は整いました. Datetimeの初期値は無くても良いですが,一応default値として現在時刻を入れておきました
ModelFormをつくる
次にさきほど作ったModelからFormをつくりましょう. mainの中にforms.pyというファイルを作ってください
touch main/forms.py
今つくったforms.pyを次のように編集してください.
from django.forms import ModelForm from main.models import BlogModel from datetimewidget.widgets import DateTimeWidget class BlogModelForm(ModelForm): class Meta: model = BlogModel fields = ("date", 'message') dateTimeOptions = { 'format': 'yyyy-mm-dd HH:ii:ss', 'autoclose': True, 'showMeridian': True } widgets = { 'date': DateTimeWidget(options=dateTimeOptions) }
modelからFormを作るために,2行目でmodelとして定義したBlogModelを呼んでます. 3行目では今回使うライブラリを呼んでます. modelという変数にはFormの元となるmodelを設定してます. fieldsではmodelの中でどれをformにするか設定してます. それぞれの変数名はDjnagoの中で決められているのでこのような名前にしてください.
dateTimeOptionsというのはDatetimeWidgetを具体的にどういうものにするか決めてます.
widgetという辞書形式の変数は今回使うライブラリを適用しているところです.
views.pyの編集
まずは次のように編集してください.
from django.shortcuts import render_to_response from django.template import RequestContext from main.models import BlogModel from main.forms import BlogModelForm def index(request): if request.method == 'POST': blogmodel = BlogModel() blogmodelform = BlogModelForm(request.POST, instance=blogmodel) if blogmodelform.is_valid(): blogmodel = blogmodelform.save(commit=False) blogmodel.save() return render_to_response('index.html', dict(form=blogmodelform, blogs=BlogModel.objects.all()), context_instance=RequestContext(request)) else: return render_to_response('index.html', dict(form=BlogModelForm(), blogs=BlogModel.objects.all()), context_instance=RequestContext(request))
簡単に解説するとblogmodelの中身と編集用のフォームをこれから作るtemplatesのindex.htmlに渡しています. POSTで飛んできたとき(index.htmlの中で投稿されたときに発生)にいろいろとしているとは思いますが,来た記事を保存して再び元の画面に戻しているだけです.
templatesをつくる
ではtemplatesにindex.htmlを作りましょう.
mkdir main/templates touch main/index.html
次にさきほどviewで渡した内容を表示してあげるようなhtmlをつくりましょう. 今回は見かけは拘らず,Django-DateTime-Fieldに必要なものだけでつくりました.
前半のscriptやcss,{{ form.media }}などの分は全て必要なのでとりあえず記述しておきましょう.
formの部分では作ったフォームを呼んできています.
{% load static from staticfiles %}<!DOCTYPE HTML> <html> <head> <title></title> <link href="{% static "bootstrap/css/bootstrap.min.css" %}" rel="stylesheet" type="text/css"/> <script src="{% static "bootstrap/js/bootstrap.js" %}"></script> <script src="{% static "jquery/jquery.min.js" %}"></script> {{ form.media }} </head> <body> <form action="" method="post"> {% csrf_token %} {{ form.as_table }} <input type="submit" value="Tweet" /> </form> {% for blog in blogs %} <h3>日付</h3> {{ blog.date }} <h3>つぶやき</h3> {{ blog.message }} {% endfor %} </body> </html>
urls.pyの設定
dtwidgetsample/urls.pyを設定しましょう
from django.conf.urls import patterns, url from main.views import index urlpatterns = patterns('', url(r'^', index), )
最後の仕上げ
ここまででひとまず全体構成を見てみましょう
. ├── db.sqlite3 ├── dtwidgetsample │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-34.pyc │ │ ├── settings.cpython-34.pyc │ │ ├── urls.cpython-34.pyc │ │ └── wsgi.cpython-34.pyc │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── main │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-34.pyc │ │ ├── admin.cpython-34.pyc │ │ ├── forms.cpython-34.pyc │ │ ├── models.cpython-34.pyc │ │ └── views.cpython-34.pyc │ ├── admin.py │ ├── forms.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── __init__.py │ │ └── __pycache__ │ │ ├── 0001_initial.cpython-34.pyc │ │ └── __init__.cpython-34.pyc │ ├── models.py │ ├── static │ │ ├── bootstrap │ │ │ ├── css │ │ │ │ ├── bootstrap-theme.css │ │ │ │ ├── bootstrap-theme.css.map │ │ │ │ ├── bootstrap-theme.min.css │ │ │ │ ├── bootstrap.css │ │ │ │ ├── bootstrap.css.map │ │ │ │ └── bootstrap.min.css │ │ │ ├── fonts │ │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ │ └── glyphicons-halflings-regular.woff │ │ │ └── js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ └── npm.js │ │ └── jquery │ │ ├── jquery.js │ │ ├── jquery.min.js │ │ └── jquery.min.map │ ├── templates │ │ └── index.html │ ├── tests.py │ └── views.py └── manage.py
こんな感じになっていればOKです.
makemigrationsやmigrateをして,起動しましょう
python manage.py makemigrations python manage.py migrate python manage.py runserver
ひっかかったところ
- ValidationでFalseになる
- YYYY-yy-dd hh:mm:ssという形式であれば無事動きましたが,USの形式などではValidationチェックで引っ掛かることがありました.