開発」カテゴリーアーカイブ

Python + Django してみた。 その3.テンプレート使ってみた。

ども、みむらんです。
第2回の続きってことで。

 

1.テンプレートとなる HTML ファイルを書く。

test_project ディレクトリ以下に templates/test_app ディレクトリを作成し、
templates/test_app ディレクトリ以下に home.html を以下の内容で作成します。

<html>
<head>
<title>{{title}}</title>
</head>
<body>
{% for i in data %}
{{i}}<br/>
{% endblock %}
</body>
</html>

{{変数}} というのを、「テンプレート変数」と呼び、
{{% タグ 引数 %}} ~ {{% end タグ %}} というのを、「タグ」と呼びます。

テンプレート変数の記述を用いて、変数の中身を表示させ、
タグの記述を用いて表示上の処理を記述する形となります。

Django テンプレート言語 — Django v1.0 documentation
ぱーっとこのページを見ていた感じでは、以下の要素がよく使われそうな気がします(ぉ

タグ名

利用用途

extends [template file] すでに定義されているテンプレートファイルを継承する。

Java での extend と同義と捉えられるかも。
block [block name] 継承元:ブロック(範囲)を定義し、継承先で値が変更される場所を設定する。

継承先:事前にブロックとして定義されている範囲のテキストを変更する。
for [val1] in [val2] val2 から要素を1つ1つ取り出し、 val1 に格納する形で、

for ~ endfor 間を繰り返す。

Java で言うところの foreach がこれに該当。

ちなみに、 Python の for は全て foreach な処理になっている。

if [条件] ~ else ~ endif

ifequal [val1] [val2] ~ endifequal

ifnotequal [val1] [val2] endnotequal

条件が真であれば、該当範囲が実行される。通常の if 条件と同じ。

ifequal は2つが等しい場合。

ifnotequal は2つが等しくない場合にそれぞれ実行される。

 

2.settings.py にテンプレートが置かれているディレクトリのパスを記述する。

TEMPLATE_DIRS = (
)

こうなっている部分があるかと思いますが、ここを下記のように書き換えます。

TEMPLATE_DIRS = (
   '[test_project までの絶対パス]/templates',
)

([test_project までの絶対パス] には、それぞれの環境に合ったパスを記述してください。)

 

3.views.py を編集する。

test_app に移動し、views.py を以下のように書き換えます。

from django.http import HttpResponse
from django.template import loader, RequestContext

def home(req):
    contexts = RequestContext(req, {
        'title' : 'hello django!',
        'data' : ('Hello', 'django', 'world'),
    })
    template = loader.get_template('test_app/home.html')
    return HttpResponse(template.render(contexts))

 

4.実行する。

image

Python + Django してみた。 その2.とりあえずページを出してみる。

どーも。みむらんです。
というわけで、 第1回 の続きとして適当にぺけぺけと。

 

1. settings.py を編集する。

settings.py を編集して、 任意のアプリケーションを読み込むように指示します。

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Uncomment the next line to enable the admin:
    # 'django.contrib.admin',
    # Uncomment the next line to enable admin documentation:
    # 'django.contrib.admindocs',
)

上記のようなことが書かれている箇所があるのですが、
そこに、

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'test_app',
)

というように、(最下行)
test_app (作成したアプリケーション名) を追記。

 

2. urls.py を編集。

urls.py を編集し、任意の URI へのアクセスを
任意のアプリケーションのコールバック関数に渡るように、 URI と関数を関連づけます。

”””
どの本読んでも、
みんなコールバック関数じゃなくて、関数やメソッドと書かれているから、関数と書いた方がいい気がしてきた。

・・他の言語での用語に合わせるならば、ハンドラとも書けそうな気がするけど、むー。 
”””

urlpatterns = patterns('',
    # Examples:
    # url(r'^$', 'test_project.views.home', name='home'),
    # url(r'^test_project/', include('test_project.foo.urls')),

    # Uncomment the admin/doc line below to enable admin documentation:
    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    # url(r'^admin/', include(admin.site.urls)),
)

デフォルトではこのようになっていますが、これを変更し、

urlpatterns = patterns('',
    (r'\$', 'test_app.views.home'),
)

という感じに。

こうすることで、全てのアクセスが、
test_app の、 views.py の中で定義されている、 home メソッドにて処理されるようになります。

第1引数は正規表現で記述しますので、
(r’^lang/(python|CSharp)/$’, ‘test_app.views.correct’)
なんて書き方も可能です。

 

3.views.py を書く。

先ほど作成した、アプリケーションのディレクトリへ移動して、
その中の views.py を編集し、処理内容を定義します。

views.py :

from django.http import HttpResponse

def home(req):
    return HttpResponse('Hello Django World !')

 

4.動かしてみる。

image

 

テキストが表示された!

Python + Django してみた。 その1.とりあえず動かしてみる。

image

どうもみむらんです。
ろーたすに「みむらん」と言われたので、 Web やるときは「みむらん」としようかな、いあいあ。

とりあえず、普段ネイティブアプリケーションや、クライアントソフトウェアをやる人が、
ウェブアプリケーションをやってみるコーナー第何弾ですよっと。

 

閑話休題

 

というわけで早速使ってみます。

 

1.下準備:インストール

$ easy_install django

これでおっけーです。

今回は Apache + mod_wsgi で行いましたが、
もしその辺の環境がそろってなくとも、単体でも実行可能なので問題ありません。

 

2.プロジェクト作成

作業ディレクトリに移動し、下記のコマンドを実行。

$ django-admin startproject testproject

 

3.アプリケーション作成

$ cd testproject
$ ./manage.py startapp testapp

2で作成したプロジェクト(上記例だと 「testproject」)のディレクトリに移動し、
startapp するだけです。

 

4. (Apache の場合のみ) mod_wsgi で動くようにする。

djangoをmod_wsgiやcgiで使うためのpythonスクリプト – ラシウラ

ここを参考に。

掲載されているスクリプトを、 index.wsgi として保存して、
.htaccess で見に行かせる。

またこのとき、以下のことを行う。

1.apps = os.path.dirname(__file__) の __file__ を settings.py のあるパスに書き換える。
2.必要に応じて、 os.environ[“DJANGO_SETTINGS_MODULE”]  の行をコメントアウト。

 

4.(スタンドアロン の場合のみ)  サーバを立ち上げる。

$ python manage.py runserver localhost:8080

 

5.アクセスする。

image

It worked! と出れば成功。

IronRuby で gem

案外知られていなさそうなのでメモメモ。

image

コマンドプロンプトを管理者権限で起動。

 

(IronRuby の bin ディレクトリにパスを通していない方は、

32bit : [ cd %ProgramFiles%\IronRuby*\bin ]
64bit : [ cd %ProgramFiles(x86)%\IronRuby*\bin ]

上記のコマンドでインストールされたディレクトリ以下の bin ディレクトリにあらかじめ移動しておきます。

 

igem コマンド

image

ということで、 gem と同等の機能については、
igem コマンド で実行可能です。

また、インストールされたパッケージについては、
バッチファイルが作成され、直接呼び出せるようになります。

 

ではでは。

Cコード中にマシン語を埋め込んで実行する。

なんだろう、何百番煎じな気がする。もうお茶も出なくなってお湯ですよ、お湯。

フォロワーの @pasberth さんが、「JIT ってどういう仕掛けになってるの!」といっていたので、
メモリ上にバイトコードを置いて実行する方法ということでちょろっと書いたものです。

とりあえず、ピタゴラスの定理をアセンブラで書いて、
C でぺけぺけ。

ひとまず、私の作業環境である Windows での動作確認。

440411299

そいでもって、x86 なら、どのプラットフォームでもバイナリ部分は変えなくても走るよ! ってのを示すために、
Mac を立ち上げて実行。

440460787

 


ソースコードは下記のような感じです。@pasberth さん用に書いたので、Mac 向けソースになってます
Windows で動かすには、先頭の vm_protect を VirtualProtect の形式に書き換えれば動きます。

 

#include <mach/mach.h>
#include <stdio.h>

/************************************************
 とりあえず、中のデータは16進で記録してあって、

リトルエンディアンですから、
 0x01020304 は、メモリ上に 0x04,0x03,0x02,0x01 の順で格納されます。
要は逆順です。

また、命令のオーダーについては、必ずしも何バイトということはありませんが、
最長命令は 32bit アーキテクチャですんで 4 バイト ( 32 bit / 8 = 4 byte. )

見やすくするために、2バイトや1バイト命令に関しては、
0x90 (NOP) [NOP = なにもしない] を挿入して、アライメント(区切り)を合わせてあります。

まー、適当に見てもらえれば。

************************************************/

int main(){
	unsigned long d;
	int a = 0,b = 0,c = 0;
	unsigned long code[32] = {0};
	
	printf("vm_protect : %s\n\n",vm_protect(
		mach_task_self(),
		(vm_address_t)code,32 * sizeof(long),
		FALSE,
			VM_PROT_READ | 
			VM_PROT_WRITE | 
			VM_PROT_EXECUTE
		) == KERN_SUCCESS ? "[OK]" : "[FALSE]");

	printf("INPUT [a,b,c] : ");
	scanf("%d,%d,%d",&a,&b,&c);

	code[0]  = 0x0424448B;	// MOV EAX,DWORD PTR SS:[ESP+4]
	code[1]  = 0x08244C8B;	// MOV ECX,DWORD PTR SS:[ESP+8]
	code[2]  = 0x9090C13B;	// CMP EAX,ECX
	code[3]  = 0x9090047E;	// JLE SHORT ; EIP+4
	code[4]  = 0x9090C88B;	// MOV ECX,EAX
	code[5]  = 0x0C24548B;	// MOV EDX,DWORD PTR SS:[ESP+C]
	code[6]  = 0x9090CA3B;	// CMP ECX,EDX
	code[7]  = 0x9090147E;	// JLE SHORT ; EIP+C
	code[8]  = 0x90909056;	// PUSH ESI
	code[9]  = 0x9090F28B;	// MOV ESI,EDX
	code[10] = 0x9090D18B;	// MOV EDX,ECX
	code[11] = 0x9090CE8B;	// MOV ECX,ESI
	code[12] = 0x9090905E;	// POP ESI
	code[13] = 0x90C0AF0F;	// IMUL EAX,EAX
	code[14] = 0x90C9AF0F;	// IMUL ECX,ECX
	code[15] = 0x90D2AF0F;	// IMUL EDX,EDX
	code[16] = 0x9090C103;	// ADD EAX,ECX
	code[17] = 0x9090C22B;	// SUB EAX,EDX
	code[18] = 0x9090D8F7;	// NEG EAX
	code[19] = 0x9090C01B;	// SBB EAX,EAX
	code[20] = 0x90909040;	// INC EAX
	code[21] = 0x909090C3;	// RETN
	
	printf("\nRETURN : %s\n",
		((int(*)(int,int,int))code)(a,b,c) == 0 ? "[FALSE]" : "[OK]");
	
	return 0;
}

 

中のバイトコード部分は、ソースコード中のコメントを見てもらえれば。

本来、こういうページ領域上にバイトコードを置いて、それを呼び出そうとしても、
実行できないように設定されています。

(実行できるようになっていると、プロセスに脆弱性があったとき、悪意のあるコードを攻撃者から送信されて、実行されてしまう危険性が格段に上がる)

ですが、さすがに完全に実行できないと、Java VM をはじめとしたソフトウェアが稼働できなくなってしまうため、
OSから実行可能にフラグを書き換えるAPIが提供されています。

OS

関数

Windows VirtualProtect
MSDN : http://msdn.microsoft.com/ja-jp/library/cc430214.aspx
Mac OS X vm_protect
The GNU Mach Reference Manual :
http://www.gnu.org/software/hurd/gnumach-doc/Memory-Attributes.html
Darwin :
http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/vm_protect.html
Linux mprotect
Man page of MPROTECT :
http://linuxjm.sourceforge.jp/html/LDP_man-pages/man2/mprotect.2.html

実行可能なバイトコードは、x86 プロセッサ共通なので、同じプロセッサならどれでも動きますが、
各オペレーティングシステムに合わせて、上記に挙げた関数を利用して、実行可能に設定する必要があります。

 

実際の JIT コンパイラなどでは、各プラットフォームごとのライブラリや、
APIの差異の吸収が必要になって、結構面倒なことになりますが、

今回の例はきわめて単純な例を使って、 x86 プロセッサ上なら同じコードが動くということを示すのと同時に、
Java などでは、こういう感じでたぶんコードを実行しているということで。

(mono はこれ使ってる感濃厚。 ソースコードを眺めていた感じでは。