Sealyu

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

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  618 随笔 :: 87 文章 :: 225 评论 :: 0 Trackbacks

最近在着手下一个项目的准备工作,我之前的项目后台都是用Coldfusion的,Coldfusion的开发速度很快 而且可靠,但是Coldfusion的价格太高了,无形会增加用户的部署成本,再而,现在做的项目除了后台部分都是搭建在开源自由的软件平台上的,如 MySQL、Linux、Flex等,既然要切换后台,那更换的方向也是如此,本来想用Java的,可最近我发现自己有点缺少激情了(项目做多了、很多都 在重复,没什么挑战性、没了新鲜感了,所有激情就欠奉了,要不是有五脏六腑需要祭奠,鬼才做这些商业项目呢)。最近社区讨论得最多的轻量的快速开发框架就 是RORDjango,ROR是好,可惜是源于日本鬼子的东西,我这人向来愤青,自然不选了,Django源于Python,Python 有如此丰富的类库及其广泛的应用,而且即将迎来里程碑版本Python3000的发布,再加上我Python荒废多时正想重新拾掇起来,所有就选中了这个 Django作为后台的框架。至于Flex与Django的通信,我用的PyAmf,之所以选用他,是因为这个支持Flex的RemoteObject。

下面是项目的准备阶段手稿,基本来自于各项目的官方文档。

假定

本文基于Ubuntu Linux,开发环境已经安装Python、mod_pythonsubversionapacheMySQL等环境。相关的安装大家可以参照各自的官方文档,这里给出Ubuntu下的安装方法(Python默认已经安装不需要安装):

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

另外,我们创建一个目录存放我们项目相关的文件:

[bash]
mkdir -p ~/works/Ananas

后续我们将使用$work_root来指代该目录。

Django的安装及相关开发环境的搭建

Django目前才出于开发过程中,其API还在陆续完善中,其实作为实际产品的应用是有风险的,当前的版本是0.96,不过我用的是svn的开发版本,以便官方有更新能够快速更新。

首先,通过一下命令下载最新的Django代码(请确保您的系统已经安装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添加到系统路径中,以便后续使用方便

[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

大家可以访问这里查看安装过程的官方说明。

创建Django工程

现在我们可以开始创建Django的工程了:

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

以上我们首先创建了一个src目录,该目录为你的Django工程根目录,接着创建一个项目ananas,初始的结构如下:

[bash]
ananas/
__init__.py
manage.py
settings.py
urls.py
其中,manage.py是工程管理工具,settings.py则是项目的相关参数设置,而urls.py则是Django的url解析表

接着我们就可以启动Django 开发服务器了:

[bash]
cd $work_root/server/src/ananas
python manage.py runserver
以上命令会启用一个Django内置的用python实现的轻量web Server,考虑到我们最终要部署到Apache上,及分布开发的情况,我们这里不使用这个方法,而是使用下面Apache+mod_python的方式。

Django的mod_python配置

首先,激活Apache的mod_python模块:

[bash]
sudo a2enmod mod_python
接着,修改apache配置文件,在集中添加Django相关的配置:

[bash]
sudo vi /etc/apache2/sites-enabled/000-default
添加在</VirtualHost>前添加如下内容:

[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要替换成您的项目根目录,也就是$work_root/server/src/,在本文中实际的配置应该是:

[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>

以上配置表示,对于/ananas的访问,使用django.core.handlers.modpython来处理,其中的PythonDebug On,打开调试功能,方便我们开发过程的程序调试,实际生产上需要关闭它。

另外,在末尾添加如下内容:

[bash]
MaxRequestsPerChild 1

该配置强制Apache对于每个请求都重新载入配置,以便我们的Python代码更新后,不需要重启Apache。该配置对Apache性能有影响,实际生产上需要删除它。

接着,启动apache:

[bash]
sudo /etc/init.d/httpd start
如果您配置正常的话,这时候访问http://127.0.0.1/ananas/,将会看到如下画面:

该部分官方的详细说明可以查看这里

配置Django数据库访问

接着我们来配置Django连接MySQL,编辑settings.py文件,修改其中的如下选项:

[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.

文件里面已经说的很清楚了 ,这个分别对应你要使用什么类型数据库服务器、要连接的数据库名、用户名、密码、数据库服务器主机地址、端口。分别安装您的实际数据库连接情况设置好就可以了。

接着修改INSTALLED_APPS部分:

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

这个部分表示在我们的Django实例中激活了那些应用,一个应用可以用于多个工程,默认的四个应用,分别对应是认证系统、内容识别、session框架和一个但Django对应多个站点的框架。

您可以根据需要添加或删除应用,比如我们这里不需要认证系统,那么直接将其修改如下:

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

接着,执行如下命令,为这些应用创建必要的表结构等:

[bash]
python manage.py syncdb

创建我们自己的应用

现在,我们已经搭建好了Django开发环境——创建了一个工程ananas,现在我们来创建我们实际的应用。

使用如下命令创建一个应用:

[bash]
python manage.py startapp users

以上将在当前目录创建一个users目录,其内容如下:

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

其中,models.py用于定义我们的数据库模型,将其修改如下:

[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

以上定义了两个表,一个是部门表、一个用户表,用户表的dep字段是指向Department的外键。关于Django里面model的定义说明请查看这里

接着在settings.py中激活我们的users应用(应用名称为:ananas.users),将其中的INSTALLED_APPS修改如下:

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

返回到工程根目录,执行以下命令,自动创建表结构:

python manage.py syncdb

以上会自动创建两个表:users_department和users_users。

初始数据的写入

现在我们可以利用Django提供的API来方便的写入我们的一些初始数据。

运行以下命令,进入交互的Python Shell:

[bash]
python manage.py shell

接着输入如下命令:

[python]
#
导入我们前面定义的model类
>>> from ananas.users.models import Department,User
#
创建两个部门
>>> dep1=Department(name='
前台接待部门')
>>> dep1.save()
>>> dep2=Department(name='
资信调查部门')
>>> dep2.save()
#
验证是否创建成功
>>> Department.objects.all()
[<Department:
前台接待部门>, <Department: 资信调查部门>]
#
创建三个用户,分别对应两个部门
#
获取部门一
>>> dep1=Department.objects.get(name='
前台接待部门')
#
当前该部门没有任何用户
>>> 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()
#
验证是否创建成功
[<User: feiy>, <User: feng>]
#
获取部门二

>>> dep2=Department.objects.get(name='
资信调查部门')
#
当前该部门没有任何用户
>>> dep2.user_set.all()
[]
>>> dep2.user_set.create(id='0003',name='eshangrao')
<User: eshangrao>
#
验证是否创建成功
>>> User.objects.all()
[<User: feiy>, <User: eshangrao>, <User: feng>]

怎么样,Django里面数据访问很方便吧,更多的Django API信息请查看这里

搭建Flex和Django的桥梁:PyAmf的安装


以上我们已经准备好了后台环境,创建了初始的数据,那么我们的Flex程序如何与Django交互呢,答案是PyAmf,这个是Python的Amf实现,通过他,Flex就可以使用Amf的方式和Python程序交互。值得一提的是,这个支持Amf3。

PyAmf
目前的稳定版本是0.1,和前面安装Django一样的考虑,我们也安装svn的开发版本

代码如下

  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工程目录下创建一个amfgateway.py文件,内容如下:

代码如下

  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.     })  

以上定义了一个userGateway Amf网关,提供了三个分别获取所有部门、用户和更新用户信息的方法。

接着打开$work_root/server/src/ananas/urls.py,定义AMF网关的访问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.  )

以上定义对/ananas/gateway的访问,使用usersGateway进行处理。(注意,这个urls.py是Django里面的最经典的东西,这样可以使用正则表达式,定义非常灵活的URL处理)

接着我们来进行Flex端的开发。

首先,为了代码分离的考虑,我们将后台Django服务配置的设置单独存放在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网关访问URL地址一致。

下面是一个简单的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="员工号" 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”>一致。

注意编译以上程序的时候,请使用“-services services-config.xml”参数加载Service配置。

posted on 2009-01-10 13:51 seal 阅读(2803) 评论(5)  编辑  收藏 所属分类: PythonFlex+ActionScript

评论

# re: Flex+PyAmf+Django+MySQL(转) 2009-01-12 11:24 ddigg
收藏了  回复  更多评论
  

# re: Flex+PyAmf+Django+MySQL(转) 2009-02-04 13:39 61
写的非常详细 收藏了
  回复  更多评论
  

# re: Flex+PyAmf+Django+MySQL(转) 2009-02-04 15:14 61
8,.10中mod_python名称已经改为python
sudo a2enmod mod_python 改为 sudo a2enmod python  回复  更多评论
  

# re: Flex+PyAmf+Django+MySQL(转) 2009-06-14 16:21 wq
我根据这个文章写了个网关,然后用pyamf 的client测试,却提示:
pyamf.remoting.RemotingError: HTTP Gateway reported status 500 Internal Server Error,网上说是utf-8编码的问题,可是我在python的代码中添加了#coding=utf-8,而且代码本身我也改为uft-8了,但还是有问题,哪位高人给我解释一下呢,我的email:njwq7906@163.com   回复  更多评论
  

# re: Flex+PyAmf+Django+MySQL(转)[未登录] 2009-08-06 17:26 sagaris
UP!UP!辛苦  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: