サーバサイド(Python/Django)とクライアントサイド(Delphi)のアプリケーションの連携をやってみる。
今回はゲストブックアプリのデータを、クライアントアプリから閲覧、投稿できるようにしてみる。
サーバサイドの用意
Djangoのアプリケーションは以前作成したゲストブックアプリを利用する。
tokibito / python-hackathon2-guestbook — Bitbucket
guestbookをINSTALLED_APPSに追加し、urls.py を書いておく。
urls.py
rom django.conf.urls.defaults import * # Uncomment the next two lines to enable the admin: from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', (r'^admin/', include(admin.site.urls)), (r'', include('guestbook.urls')), # added )
syncdbでテーブルを作成してから、runserverコマンドでローカルサーバを実行して投稿出来るか確かめておく。
XML出力の作成
投稿データをXMLで出力するページを作成する。
XMLの生成に補助用のライブラリを使う。プロジェクトにxmlutilsディレクトリをコピーしておく。
tokibito / python-xmlutils — Bitbucket
startappコマンドで api アプリを作成して views.py と urls.py を書く。
myproject/api/views.py
from django.http import HttpResponse from xmlutils import XMLRenderer, dict_to_node from guestbook.models import Greeting def index(request): xmldic = {'greetings': map( lambda g: { 'greeting': { 'id': str(g.id), 'username': g.username, 'content':g.content } }, Greeting.objects.all() ) } return HttpResponse( XMLRenderer().render(dict_to_node(xmldic), indent=2, unichar=True), content_type='application/xml' )
PEP8なにそれな勢いのインデントだけど、気にしない。
myproject/api/urls.py
from django.conf.urls.defaults import * urlpatterns = patterns('api.views', (r'^$', 'index'), )
myproject/urls.py
from django.conf.urls.defaults import * # Uncomment the next two lines to enable the admin: from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', (r'^admin/', include(admin.site.urls)), (r'^api/', include('api.urls')), # added (r'', include('guestbook.urls')), )
これで http://localhost:8000/api/ でアクセスするとXMLが出てるはず。
出力結果例
<?xml version="1.0" encoding="utf-8"?> <greetings> <greeting> <username>テスト</username> <content>ほげふが</content> <id>14</id> </greeting> <greeting> <username>aaaa</username> <content>test</content> <id>13</id> </greeting> </greetings>
これでサーバサイドの用意は完了。
クライアントアプリの作成
Delphi2009Proで作成した。
出力されたXMLをファイルにダウンロードして、XMLデータバインディングを利用して取り込む。
データバインディングの例は過去の記事参照。
DelphiでTwitterのタイムラインを取得する - 偏った言語信者の垂れ流し
ボタンクリックで、XMLデータをダウンロードしてリストに表示、投稿をできるようにしている。
Unit1.pas
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, XMLDoc, HTTPApp, api; type TForm1 = class(TForm) btnReload: TButton; lvContents: TListView; txtGetXMLURL: TEdit; btnSend: TButton; txtPostURL: TEdit; txtUserName: TEdit; txtContent: TMemo; procedure btnReloadClick(Sender: TObject); procedure btnSendClick(Sender: TObject); private { Private 宣言 } public { Public 宣言 } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.btnReloadClick(Sender: TObject); var HTTP: TIdHTTP; XML: TXMLDocument; I: Integer; Item: TListItem; Greetings: IXMLGreetingsType; begin lvContents.Clear; HTTP := TIdHTTP.Create; try XML := TXMLDocument.Create(Self); try XML.LoadFromXML(HTTP.Get(txtGetXMLURL.Text)); Greetings := Getgreetings(XML); for I := 0 to Greetings.Count - 1 do begin Item := lvContents.Items.Add; Item.Caption := IntToStr(Greetings.Greeting[I].Id); Item.SubItems.Add(Greetings.Greeting[I].UserName); Item.SubItems.Add(Greetings.Greeting[I].Content); end; finally XML.Free; end; finally HTTP.Free; end; end; procedure TForm1.btnSendClick(Sender: TObject); var HTTP: TIdHTTP; PostData: TStringList; begin if (txtUserName.Text <> '') and (txtContent.Lines.Text <> '') then begin HTTP := TIdHTTP.Create; try PostData := TStringList.Create; PostData.Add('username=' + txtUserName.Text); PostData.Add('content=' + txtContent.Text); try try HTTP.Post(txtPostURL.Text, PostData); except on e: EIdHTTPProtocolException do if e.ErrorCode = 302 then OutputDebugString('Response 302.'); end; txtContent.Clear; finally PostData.Free; end; finally HTTP.Free; end; end; end; end.
投稿はフォームからPOSTするのと同じURLを使って、同様にPOSTするようにしている。