Sealyu

          --- 博客已遷移至: http://www.sealyu.com/blog

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            618 隨筆 :: 87 文章 :: 225 評(píng)論 :: 0 Trackbacks

          最近在著手下一個(gè)項(xiàng)目的準(zhǔn)備工作,我之前的項(xiàng)目后臺(tái)都是用Coldfusion的,Coldfusion的開發(fā)速度很快 而且可靠,但是Coldfusion的價(jià)格太高了,無形會(huì)增加用戶的部署成本,再而,現(xiàn)在做的項(xiàng)目除了后臺(tái)部分都是搭建在開源自由的軟件平臺(tái)上的,如 MySQL、Linux、Flex等,既然要切換后臺(tái),那更換的方向也是如此,本來想用Java的,可最近我發(fā)現(xiàn)自己有點(diǎn)缺少激情了(項(xiàng)目做多了、很多都 在重復(fù),沒什么挑戰(zhàn)性、沒了新鮮感了,所有激情就欠奉了,要不是有五臟六腑需要祭奠,鬼才做這些商業(yè)項(xiàng)目呢)。最近社區(qū)討論得最多的輕量的快速開發(fā)框架就 是RORDjango,ROR是好,可惜是源于日本鬼子的東西,我這人向來憤青,自然不選了,Django源于Python,Python 有如此豐富的類庫及其廣泛的應(yīng)用,而且即將迎來里程碑版本Python3000的發(fā)布,再加上我Python荒廢多時(shí)正想重新拾掇起來,所有就選中了這個(gè) Django作為后臺(tái)的框架。至于Flex與Django的通信,我用的PyAmf,之所以選用他,是因?yàn)檫@個(gè)支持Flex的RemoteObject。

          下面是項(xiàng)目的準(zhǔn)備階段手稿,基本來自于各項(xiàng)目的官方文檔。

          假定

          本文基于Ubuntu Linux,開發(fā)環(huán)境已經(jīng)安裝Python、mod_pythonsubversionapacheMySQL等環(huán)境。相關(guān)的安裝大家可以參照各自的官方文檔,這里給出Ubuntu下的安裝方法(Python默認(rèn)已經(jīng)安裝不需要安裝):

          [bash]
          sudo apt-get install apache2 libapache2-mod-python Subversion mysql-server mysql-client

          另外,我們創(chuàng)建一個(gè)目錄存放我們項(xiàng)目相關(guān)的文件:

          [bash]
          mkdir -p ~/works/Ananas

          后續(xù)我們將使用$work_root來指代該目錄。

          Django的安裝及相關(guān)開發(fā)環(huán)境的搭建

          Django目前才出于開發(fā)過程中,其API還在陸續(xù)完善中,其實(shí)作為實(shí)際產(chǎn)品的應(yīng)用是有風(fēng)險(xiǎn)的,當(dāng)前的版本是0.96,不過我用的是svn的開發(fā)版本,以便官方有更新能夠快速更新。

          首先,通過一下命令下載最新的Django代碼(請(qǐng)確保您的系統(tǒng)已經(jīng)安裝Subversion):

          [bash]
          cd $work_root
          mkdir -p server&& cd server
          svn co http://code.djangoproject.com/svn/django/trunk/ django-trunk
          接著將Django加載到Python解析路徑中:

          [bash]
          sudo ln -s $work_root/server/django-trunk/django "
          python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"`/django

          接著將django-admin.py添加到系統(tǒng)路徑中,以便后續(xù)使用方便

          [bash]

          sudo ln -s $work_root/server/django-trunk/django/bin/django-admin.py /usr/local/bin
          以后如果要更新Django,直接使用如下方法更新:

          [bash]
          cd $work_root/server/django-trunk
          svn update

          大家可以訪問這里查看安裝過程的官方說明。

          創(chuàng)建Django工程

          現(xiàn)在我們可以開始創(chuàng)建Django的工程了:

          [bash]
          mkdir $work_root/server/src&&cd $work_root/server/src
          django-admin.py startproject ananas

          以上我們首先創(chuàng)建了一個(gè)src目錄,該目錄為你的Django工程根目錄,接著創(chuàng)建一個(gè)項(xiàng)目ananas,初始的結(jié)構(gòu)如下:

          [bash]
          ananas/
          __init__.py
          manage.py
          settings.py
          urls.py
          其中,manage.py是工程管理工具,settings.py則是項(xiàng)目的相關(guān)參數(shù)設(shè)置,而urls.py則是Django的url解析表

          接著我們就可以啟動(dòng)Django 開發(fā)服務(wù)器了:

          [bash]
          cd $work_root/server/src/ananas
          python manage.py runserver
          以上命令會(huì)啟用一個(gè)Django內(nèi)置的用python實(shí)現(xiàn)的輕量web Server,考慮到我們最終要部署到Apache上,及分布開發(fā)的情況,我們這里不使用這個(gè)方法,而是使用下面Apache+mod_python的方式。

          Django的mod_python配置

          首先,激活A(yù)pache的mod_python模塊:

          [bash]
          sudo a2enmod mod_python
          接著,修改apache配置文件,在集中添加Django相關(guān)的配置:

          [bash]
          sudo vi /etc/apache2/sites-enabled/000-default
          添加在</VirtualHost>前添加如下內(nèi)容:

          [bash]
          <Location "/ananas/">
          SetHandler python-program
          PythonHandler django.core.handlers.modpython
          SetEnv DJANGO_SETTINGS_MODULE ananas.settings
          PythonDebug On
          PythonPath "['/path/to/project'] + sys.path"
          </Location>

          其中,/path/to/project要替換成您的項(xiàng)目根目錄,也就是$work_root/server/src/,在本文中實(shí)際的配置應(yīng)該是:

          [bash]
          <Location "/ananas/">
          SetHandler python-program
          PythonHandler django.core.handlers.modpython
          SetEnv DJANGO_SETTINGS_MODULE ananas.settings
          PythonDebug On
          PythonPath "['/home/feiy/works/Ananas/server/src'] + sys.path"
          </Location>

          以上配置表示,對(duì)于/ananas的訪問,使用django.core.handlers.modpython來處理,其中的PythonDebug On,打開調(diào)試功能,方便我們開發(fā)過程的程序調(diào)試,實(shí)際生產(chǎn)上需要關(guān)閉它。

          另外,在末尾添加如下內(nèi)容:

          [bash]
          MaxRequestsPerChild 1

          該配置強(qiáng)制Apache對(duì)于每個(gè)請(qǐng)求都重新載入配置,以便我們的Python代碼更新后,不需要重啟Apache。該配置對(duì)Apache性能有影響,實(shí)際生產(chǎn)上需要?jiǎng)h除它。

          接著,啟動(dòng)apache:

          [bash]
          sudo /etc/init.d/httpd start
          如果您配置正常的話,這時(shí)候訪問http://127.0.0.1/ananas/,將會(huì)看到如下畫面:

          該部分官方的詳細(xì)說明可以查看這里

          配置Django數(shù)據(jù)庫訪問

          接著我們來配置Django連接MySQL,編輯settings.py文件,修改其中的如下選項(xiàng):

          [python]
          DATABASE_ENGINE = ''           # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
          DATABASE_NAME = ''             # Or path to database file if using sqlite3.
          DATABASE_USER = ''             # Not used with sqlite3.
          DATABASE_PASSWORD = ''        # Not used with sqlite3.
          DATABASE_HOST = ''             # Set to empty string for localhost. Not used with sqlite3.
          DATABASE_PORT = ''             # Set to empty string for default. Not used with sqlite3.

          文件里面已經(jīng)說的很清楚了 ,這個(gè)分別對(duì)應(yīng)你要使用什么類型數(shù)據(jù)庫服務(wù)器、要連接的數(shù)據(jù)庫名、用戶名、密碼、數(shù)據(jù)庫服務(wù)器主機(jī)地址、端口。分別安裝您的實(shí)際數(shù)據(jù)庫連接情況設(shè)置好就可以了。

          接著修改INSTALLED_APPS部分:

          [python]
          INSTALLED_APPS = (
          'django.contrib.auth',
          'django.contrib.contenttypes',
          'django.contrib.sessions',
          'django.contrib.sites',
          )

          這個(gè)部分表示在我們的Django實(shí)例中激活了那些應(yīng)用,一個(gè)應(yīng)用可以用于多個(gè)工程,默認(rèn)的四個(gè)應(yīng)用,分別對(duì)應(yīng)是認(rèn)證系統(tǒng)、內(nèi)容識(shí)別、session框架和一個(gè)但Django對(duì)應(yīng)多個(gè)站點(diǎn)的框架。

          您可以根據(jù)需要添加或刪除應(yīng)用,比如我們這里不需要認(rèn)證系統(tǒng),那么直接將其修改如下:

          [python]
          INSTALLED_APPS = (
          'django.contrib.contenttypes',
          'django.contrib.sessions',
          'django.contrib.sites',
          )

          接著,執(zhí)行如下命令,為這些應(yīng)用創(chuàng)建必要的表結(jié)構(gòu)等:

          [bash]
          python manage.py syncdb

          創(chuàng)建我們自己的應(yīng)用

          現(xiàn)在,我們已經(jīng)搭建好了Django開發(fā)環(huán)境——?jiǎng)?chuàng)建了一個(gè)工程ananas,現(xiàn)在我們來創(chuàng)建我們實(shí)際的應(yīng)用。

          使用如下命令創(chuàng)建一個(gè)應(yīng)用:

          [bash]
          python manage.py startapp users

          以上將在當(dāng)前目錄創(chuàng)建一個(gè)users目錄,其內(nèi)容如下:

          [bash]
          users/
          __init__.py
          models.py
          views.py

          其中,models.py用于定義我們的數(shù)據(jù)庫模型,將其修改如下:

          [python]
          from django.db import models

          class Department(models.Model):

                  name = models.CharField(max_length=80)

                  def __unicode__(self):

                         return self.name

          class User(models.Model):

                  id=models.CharField(max_length=8,primary_key=True)

                  name = models.CharField(max_length=40)

                  dep = models.ForeignKey(Department)

                  def __unicode__(self):

                         return self.name

          以上定義了兩個(gè)表,一個(gè)是部門表、一個(gè)用戶表,用戶表的dep字段是指向Department的外鍵。關(guān)于Django里面model的定義說明請(qǐng)查看這里

          接著在settings.py中激活我們的users應(yīng)用(應(yīng)用名稱為:ananas.users),將其中的INSTALLED_APPS修改如下:

          [python]
          INSTALLED_APPS = (
          'django.contrib.contenttypes',
          'django.contrib.sessions',
          'django.contrib.sites',
          'ananas.users',
          )

          返回到工程根目錄,執(zhí)行以下命令,自動(dòng)創(chuàng)建表結(jié)構(gòu):

          python manage.py syncdb

          以上會(huì)自動(dòng)創(chuàng)建兩個(gè)表:users_department和users_users。

          初始數(shù)據(jù)的寫入

          現(xiàn)在我們可以利用Django提供的API來方便的寫入我們的一些初始數(shù)據(jù)。

          運(yùn)行以下命令,進(jìn)入交互的Python Shell:

          [bash]
          python manage.py shell

          接著輸入如下命令:

          [python]
          #
          導(dǎo)入我們前面定義的model類
          >>> from ananas.users.models import Department,User
          #
          創(chuàng)建兩個(gè)部門
          >>> dep1=Department(name='
          前臺(tái)接待部門')
          >>> dep1.save()
          >>> dep2=Department(name='
          資信調(diào)查部門')
          >>> dep2.save()
          #
          驗(yàn)證是否創(chuàng)建成功
          >>> Department.objects.all()
          [<Department:
          前臺(tái)接待部門>, <Department: 資信調(diào)查部門>]
          #
          創(chuàng)建三個(gè)用戶,分別對(duì)應(yīng)兩個(gè)部門
          #
          獲取部門一
          >>> dep1=Department.objects.get(name='
          前臺(tái)接待部門')
          #
          當(dāng)前該部門沒有任何用戶
          >>> dep1.user_set.all()
          []
          >>> dep1.user_set.create(id='0001',name='feiy')
          <User: feiy>
          >>> dep1.user_set.create(id='0002',name='feng')
          <User: feng>
          >>> dep1.user_set.all()
          #
          驗(yàn)證是否創(chuàng)建成功
          [<User: feiy>, <User: feng>]
          #
          獲取部門二

          >>> dep2=Department.objects.get(name='
          資信調(diào)查部門')
          #
          當(dāng)前該部門沒有任何用戶
          >>> dep2.user_set.all()
          []
          >>> dep2.user_set.create(id='0003',name='eshangrao')
          <User: eshangrao>
          #
          驗(yàn)證是否創(chuàng)建成功
          >>> User.objects.all()
          [<User: feiy>, <User: eshangrao>, <User: feng>]

          怎么樣,Django里面數(shù)據(jù)訪問很方便吧,更多的Django API信息請(qǐng)查看這里

          搭建Flex和Django的橋梁:PyAmf的安裝


          以上我們已經(jīng)準(zhǔn)備好了后臺(tái)環(huán)境,創(chuàng)建了初始的數(shù)據(jù),那么我們的Flex程序如何與Django交互呢,答案是PyAmf,這個(gè)是Python的Amf實(shí)現(xiàn),通過他,F(xiàn)lex就可以使用Amf的方式和Python程序交互。值得一提的是,這個(gè)支持Amf3。

          PyAmf
          目前的穩(wěn)定版本是0.1,和前面安裝Django一樣的考慮,我們也安裝svn的開發(fā)版本

          代碼如下

          1. cd $work_root/server  
          2. svn co http://svn.pyamf.org/pyamf/trunk pyamf-trunk  
          3. cd pyamf-trunk  
          4. sudo python setup.py develop

          接著在我們的Django工程目錄下創(chuàng)建一個(gè)amfgateway.py文件,內(nèi)容如下:

          代碼如下

          1. from pyamf.remoting.gateway.django import DjangoGateway  
          2. from ananas.users.models import Department,User
          3. def getAllDepartments(request):  
          4.     return Department.objects.all()
          5. def getDepAllUsers(request,depID):  
          6.      dep=Department.objects.get(id=depID) 
          7.     return dep.user_set.all()
          8. def updateUser(request,userID,userName,depID):  
          9.      user=User.objects.get(id=userID)  
          10.      user.name=userName  
          11.      user.depID=depID
          12. usersGateway = DjangoGateway({  
          13.   'getDepAllUsers': getDepAllUsers,  
          14.   'getAllDepartments':getAllDepartments,  
          15.   'updateUser':updateUser 
          16.     })  

          以上定義了一個(gè)userGateway Amf網(wǎng)關(guān),提供了三個(gè)分別獲取所有部門、用戶和更新用戶信息的方法。

          接著打開$work_root/server/src/ananas/urls.py,定義AMF網(wǎng)關(guān)的訪問URL,用于Flex端訪問。

          代碼如下

          1. from django.conf.urls.defaults import *  
          2. urlpatterns = patterns('',  
          3.      Example:  
          4.      (r'^ananas/', include('ananas.foo.urls')),  
          5.    
          6.      Uncomment this for admin:  
          7.      (r'^admin/', include('django.contrib.admin.urls')),  
          8.      (r'^ananas/gateway/', 'ananas.amfgateway.usersGateway'),  
          9.  )

          以上定義對(duì)/ananas/gateway的訪問,使用usersGateway進(jìn)行處理。(注意,這個(gè)urls.py是Django里面的最經(jīng)典的東西,這樣可以使用正則表達(dá)式,定義非常靈活的URL處理)

          接著我們來進(jìn)行Flex端的開發(fā)。

          首先,為了代碼分離的考慮,我們將后臺(tái)Django服務(wù)配置的設(shè)置單獨(dú)存放在services-config.xml文件里面:

          代碼如下

          1. <?xmlversion="1.0"encoding="UTF-8"?> 
          2. <services-config> 
          3. <services> 
          4. <serviceid="ananasService"class="flex.messaging.services.RemotingService"messageTypes="flex.messaging.messages.RemotingMessage"> 
          5. <destinationid="ananasAmf"> 
          6.    <channels>  
          7.    <channelref="ananasChannel"/>  
          8.    </channels>  
          9.   <properties>  
          10.   <source>*</source>  
          11.   </properties>  
          12.   </destination>  
          13.   </service>  
          14.   </services>  
          15.   <channels>  
          16.   <channel-definitionid="ananasChannel"class="mx.messaging.channels.AMFChannel">  
          17.   <endpointuri="http://127.0.0.1/ananas/gateway/"class="flex.messaging.endpoints.AMFEndpoint"/>  
          18.   </channel-definition>  
          19.   </channels>  
          20.   </services-config>  

          注意,其中<endpoint />里面的uri地址就是我們前面在Django的urls.py中定義的PyAMF網(wǎng)關(guān)訪問URL地址一致。

          下面是一個(gè)簡單的Flex的測試代碼:

          代碼如下

          1. <?xml version="1.0" encoding="utf-8"?> 
          2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="getAllDepartment()"> 
          3.     <mx:Script>  
          4.        <![CDATA[
          5.            import mx.rpc.AsyncToken;
          6.            import mx.rpc.AsyncResponder;
          7.            import mx.rpc.events.FaultEvent;
          8.            import mx.rpc.events.ResultEvent;
          9.            import mx.controls.Alert;
          10.  
          11.            private function getAllDepartment():void{
          12.                var token:AsyncToken=djangoService.getAllDepartments();
          13.                token.addResponder(new AsyncResponder(AfterGetDeps,falutHandler));
          14.            }
          15.            [Bindable]
          16.            private var depAC:Array;
          17.            private function AfterGetDeps(result:Object, token:Object=null):void{
          18.                var evt:ResultEvent=result as ResultEvent;
          19.                depAC=evt.result as Array;
          20.            }
          21.            private function falutHandler(error:Object, token:Object=null):void{
          22.                var evt:FaultEvent=error as FaultEvent;
          23.                Alert.show(evt.message.toString());
          24.            }
          25.  
          26.            [Bindable]
          27.            private var userAC:Array;
          28.            private function doQueryUser():void{
          29.                var token:AsyncToken=djangoService.getDepAllUsers(dep_cb.selectedItem.id);
          30.                token.addResponder(new AsyncResponder(AfterGetUsers,falutHandler));
          31.            }
          32.            private function AfterGetUsers(result:Object, token:Object=null):void{
          33.                var evt:ResultEvent=result as ResultEvent;
          34.                userAC=evt.result as Array;
          35.            }
          36.        ]]>  
          37.    </mx:Script> 
          38.     <mx:RemoteObject 
          39.        id="djangoService" 
          40.        destination="ananasAmf" 
          41.        showBusyCursor="true"/> 
          42.     <mx:Panel title="用戶管理"> 
          43.         <mx:DataGrid dataProvider="{userAC}">  
          44.         <mx:columns>  
          45.             <mx:DataGridColumn dataField="id" headerText="員工號(hào)" width="100"/> 
          46.             <mx:DataGridColumn dataField="name" headerText="姓名" width="200"/> 
          47.         </mx:columns>  
          48.     </mx:DataGrid>  
          49.         <mx:ControlBar>  
          50.             <mx:ComboBox id="dep_cb" dataProvider="{depAC}" labelField="name"/>  
          51.             <mx:Button label="查詢" click="doQueryUser()"/> 
          52.         </mx:ControlBar>  
          53.     </mx:Panel>  
          54. </mx:Application> 


          注意其中,<RemoteObject/>的destination=”ananasAmf”與我們前面的services-config.xml中定義的<destination id=”ananasAmf”>一致。

          注意編譯以上程序的時(shí)候,請(qǐng)使用“-services services-config.xml”參數(shù)加載Service配置。

          posted on 2009-01-10 13:51 seal 閱讀(2831) 評(píng)論(5)  編輯  收藏 所屬分類: PythonFlex+ActionScript

          評(píng)論

          # re: Flex+PyAmf+Django+MySQL(轉(zhuǎn)) 2009-01-12 11:24 ddigg
          收藏了  回復(fù)  更多評(píng)論
            

          # re: Flex+PyAmf+Django+MySQL(轉(zhuǎn)) 2009-02-04 13:39 61
          寫的非常詳細(xì) 收藏了
            回復(fù)  更多評(píng)論
            

          # re: Flex+PyAmf+Django+MySQL(轉(zhuǎn)) 2009-02-04 15:14 61
          8,.10中mod_python名稱已經(jīng)改為python
          sudo a2enmod mod_python 改為 sudo a2enmod python  回復(fù)  更多評(píng)論
            

          # re: Flex+PyAmf+Django+MySQL(轉(zhuǎn)) 2009-06-14 16:21 wq
          我根據(jù)這個(gè)文章寫了個(gè)網(wǎng)關(guān),然后用pyamf 的client測試,卻提示:
          pyamf.remoting.RemotingError: HTTP Gateway reported status 500 Internal Server Error,網(wǎng)上說是utf-8編碼的問題,可是我在python的代碼中添加了#coding=utf-8,而且代碼本身我也改為uft-8了,但還是有問題,哪位高人給我解釋一下呢,我的email:njwq7906@163.com   回復(fù)  更多評(píng)論
            

          # re: Flex+PyAmf+Django+MySQL(轉(zhuǎn))[未登錄] 2009-08-06 17:26 sagaris
          UP!UP!辛苦  回復(fù)  更多評(píng)論
            

          主站蜘蛛池模板: 桓仁| 玉田县| 临沧市| 沙雅县| 宝鸡市| 延津县| 莱阳市| 新和县| 泸定县| 巴东县| 马关县| 泽普县| 兴宁市| 兴文县| 六盘水市| 固原市| 元阳县| 白水县| 沧州市| 柏乡县| 曲水县| 宁南县| 麻城市| 明水县| 桃园县| 中方县| 德化县| 安庆市| 同心县| 扎鲁特旗| 河池市| 温泉县| 广水市| 广河县| 兴安盟| 兴化市| 石狮市| 南召县| 民县| 城口县| 九龙县|