這兩天在學習Google AppEngine的時候, 需要寫一個小程序,就是簡單的從數據庫里讀出數據,然后顯示出來。
界面使用flex的,所以數據通信是想到了用amf,搜索到了兩個python的開源產品--pyAmf和Django Amf,后來看到Django Amf更新的并不頻繁,所以最后選了pyAmf。
pyAmf還有一個優點是官方網站推薦了幾篇django與flex通信的文章里有一篇是中文的,哈哈。。。我喜歡中文。。。鏈接見
http://blog.eshangrao.com/index.php/2008/02/16/447-flexpyamfdjango
我的程序參考的也就是這篇文章,但代碼寫完后,程序并沒有通過,而是一直報找不到服務,折騰了兩天終于搞出來了。
Django 服務端,
1. 新建立一個工程testAMF,然后建立一個app--dailystory.
2. 修改settings.py
將dailystory添加到INSTALLED_APPS中。
配置數據庫。
3. 工程目錄中( whatidisplay 文件夾里 )的urls.py 的相關代碼如下:
- from django.conf.urls.defaults import *
- import settings
-
- urlpatterns = patterns('',
- (r'^dailystory/', include('testAMF.dailystory.urls')),
- (r'^admin/', include('django.contrib.admin.urls')),
- )
from django.conf.urls.defaults import *
import settings
urlpatterns = patterns('',
(r'^dailystory/', include('testAMF.dailystory.urls')),
(r'^admin/', include('django.contrib.admin.urls')),
)
4. 在dailystory文件夾中添加一個urls.py文件
- from django.conf.urls.defaults import *
-
- urlpatterns = patterns('',
- (r'^gateway/$', 'testAMF.dailystory.amfgateway.storyGateway'),
- (r'^(.*)$', 'django.views.static.serve', {'document_root':'dailystory/flex'}),
- )
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^gateway/$', 'testAMF.dailystory.amfgateway.storyGateway'),
(r'^(.*)$', 'django.views.static.serve', {'document_root':'dailystory/flex'}),
)
5. 修改dailystory文件夾中的models.py 文件
- from django.db import models
-
- class DailyStory(models.Model):
- content = models.TextField()
-
- def __unicode__(self):
- return self.title
-
- class Admin:
- pass
from django.db import models
class DailyStory(models.Model):
content = models.TextField()
def __unicode__(self):
return self.title
class Admin:
pass
6. 在dailystory文件夾中添加一個amfgateway.py文件
- from pyamf.remoting.gateway.django import DjangoGateway
- from dailystory.models import DailyStory
-
- def getDailyStory(request):
- return DailyStory.objects.all()
-
-
- storyGateway = DjangoGateway({
- 'dailystory.getDailyStory': getDailyStory,
- })
from pyamf.remoting.gateway.django import DjangoGateway
from dailystory.models import DailyStory
def getDailyStory(request):
return DailyStory.objects.all()
storyGateway = DjangoGateway({
'dailystory.getDailyStory': getDailyStory,
})
Django的服務端就大功告成了
Flex端更簡單
- <?xml version="1.0" encoding="utf-8"?>
- <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
- layout="absolute" creationComplete="initApp();">
-
- <mx:Script>
- <![CDATA[
- import flash.events.NetStatusEvent;
-
- import mx.collections.ArrayCollection;
- import mx.rpc.AsyncToken;
- import mx.rpc.AsyncResponder;
- import mx.rpc.events.FaultEvent;
- import mx.rpc.events.ResultEvent;
-
- private function initApp():void
- {
-
- var token:AsyncToken=djangoService.getDailyStory();
- token.addResponder(new AsyncResponder(onGetDailyStory,faultHandler));
- }
-
- private function onGetDailyStory(re:ResultEvent, token:Object=null):void
- {
- var stories:Array = re.result as Array;
- var storyCollection:ArrayCollection = new ArrayCollection(stories);
- yesterdayStory.text = storyCollection.getItemAt(0).content;
- }
-
- private function faultHandler(fe:FaultEvent, token:Object=null):void
- {
- trace(fe.fault.faultDetail);
- }
- ]]>
- </mx:Script>
-
- <mx:RemoteObject
- id="djangoService"
- destination="dailystory"
- showBusyCursor="true">
- </mx:RemoteObject>
-
- <mx:TextArea id="yesterdayStory" x="582" y="130" height="118" width="242"/>
- </mx:Application>
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" creationComplete="initApp();">
<mx:Script>
<![CDATA[
import flash.events.NetStatusEvent;
import mx.collections.ArrayCollection;
import mx.rpc.AsyncToken;
import mx.rpc.AsyncResponder;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
private function initApp():void
{
var token:AsyncToken=djangoService.getDailyStory();
token.addResponder(new AsyncResponder(onGetDailyStory,faultHandler));
}
private function onGetDailyStory(re:ResultEvent, token:Object=null):void
{
var stories:Array = re.result as Array;
var storyCollection:ArrayCollection = new ArrayCollection(stories);
yesterdayStory.text = storyCollection.getItemAt(0).content;
}
private function faultHandler(fe:FaultEvent, token:Object=null):void
{
trace(fe.fault.faultDetail);
}
]]>
</mx:Script>
<mx:RemoteObject
id="djangoService"
destination="dailystory"
showBusyCursor="true">
</mx:RemoteObject>
<mx:TextArea id="yesterdayStory" x="582" y="130" height="118" width="242"/>
</mx:Application>
然后需要在于與上述flex文件同目錄中新建一個services-config.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <services-config>
- <services>
- <service id="dailyStoryService" class="flex.messaging.services.RemotingService" messageTypes="flex.messaging.messages.RemotingMessage">
- <destination id="dailystory">
- <channels>
- <channel ref="dailyStoryChannel"/>
- </channels>
- <properties>
- <source>*</source>
- </properties>
- </destination>
- </service>
- </services>
- <channels>
- <channel-definition id="dailyStoryChannel" class="mx.messaging.channels.AMFChannel">
- <endpoint uri="http://localhost:8080/dailystory/gateway/" class="flex.messaging.endpoints.AMFEndpoint"/>
- </channel-definition>
- </channels>
- </services-config>
<?xml version="1.0" encoding="UTF-8"?>
<services-config>
<services>
<service id="dailyStoryService" class="flex.messaging.services.RemotingService" messageTypes="flex.messaging.messages.RemotingMessage">
<destination id="dailystory">
<channels>
<channel ref="dailyStoryChannel"/>
</channels>
<properties>
<source>*</source>
</properties>
</destination>
</service>
</services>
<channels>
<channel-definition id="dailyStoryChannel" class="mx.messaging.channels.AMFChannel">
<endpoint uri="http://localhost:8080/dailystory/gateway/" class="flex.messaging.endpoints.AMFEndpoint"/>
</channel-definition>
</channels>
</services-config>
在編譯時注意添加編譯參數-services services-config.xml
然后將編譯后生成的在bin-debug文件夾中的文件復制到whatidisplay"dailystory"flex文件夾里
運行django服務器
訪問
http://localhost:8080/dailystory/DailyStory.html
這里與我參考的文章不同的有兩點,估計是pyAMF的更新造成的。我用的pyamf版本是0.3.1.
第一個是在amfgateway.py文件中
- storyGateway = DjangoGateway({
- 'dailystory.getDailyStory': getDailyStory,
- })
storyGateway = DjangoGateway({
'dailystory.getDailyStory': getDailyStory,
})
我在給DjangoGateway賦值時使用了
appName.method--即
dailystory.getDailyStory
據官方說這可能是個bug;)具體參看
http://www.pyamf.org/wiki/DjangoHowto中的May be some problems here
另外一處是
services-config.xml 文件中,我的
destination id 給的就是django中App的名字。如果起其他名字的話,最后flex總是得不到服務。很奇怪。