Django AMF User Manual †Last Updated: 2008-12-11 (Thu) 23:01:59 JST System Requirements †
Installation †
Settings †
AMF_GATEWAY_PATH = '/gateway/' AMF_LOG_LEVEL = 'INFO' AMF_LOG_FILE = '/path/to/log.txt' AMF_LOG_FILE_ENCODING = 'utf8' AMF_LOG_FILE_MODE = 'a' Data Types †Data types are automatically converted between Flash/Flex and Django AMF. Flash/Flex -> Python †AMF3
AMF0
Python -> Flash/Flex †AMF3
AMF0
Types other than listed above are treated as custom classes. For details, refer to Custom Class Mapping section. QuerySet and its subclass object returned by Django Database API is treated as python list type. Django AMF does not support RecordSet. ByteArray type †Because Python deal with byte array data as string, Django AMF provides amf.ByteArray class which wraps ByteArray typed data sent from Flash/Flex application. Example import amf
def saveByteArrayData(request, bytearray):
"""
Saves to a file the ByteArray data sent from Flash/Flex.
"""
data = bytearray.data
f = open('filename', 'wb')
f.write(data)
f.close
def getByteArrayData(request):
"""
Returns the ByteArray data of a file.
"""
f = open('filename', 'rb')
data = f.read()
f.close()
return amf.ByteArray(data)
View implementation for remoting service †Remoting service methods are implemented in a view module for Django. For Django view, refere to the page below: As view functions for HTML response, the first argument of a view function is HTTPRequest object. HTTPRequest object is passed by Django automatically, so Flash/Flex application need not care about it. Example
#1 'calculate' function specifies arg1, arg2 arguments. In the funciton, add arg1 value and arg2 value, then return the result value. (If the arguments are string types, string concatenation result is returned.) #2 'calculate2' function specifies obj as a argument which is supposed to be dict type holding arg1 and arg2 key. Add these key values and put the result to obj['sum'], then return the object. Flash/Flex receives this return value as Object type object. #3 'getCurrentDateTime' function does not need any argument. It returns the datetime object representing the current time. Flash/Flex receives Date type object from this remoting service method. #4 'getAllCustomers' function returns QuerySet of Customer class objects. Flash/Flex retrieves the returned value as Array. If Customer class is mapped to an ActionScript class using Custom Class Mapping, the elements of the Array are the mapped ActionScript class objects. Otherwise, the elements are Object type objects. View function for remoting service returns the object which Flash/Flex application wants to receive as a result value of the remoting method. Expose Remoting Service †To expose a view module as remoting service, add to URLConf a url pattern following the rule below: (r'^{AMF_GATEWAY_PATH}/{Remoting Service Name}/(.*)', 'amf.django.views', {'views':'{View Module Name}'})
or (r'^{AMF_GATEWAY_PATH}/{Remoting Service Name}/{Method Name}', '{View Function Name}')
{Remoting Service Name} and {Method Name} can be any value. The first pattern is called 'Auto Method Mapping', which invokes the same name view function as remoting service method called by Flash/Flex application. Example
Remoting Service Invocation from Flash/Flex †Example of calling calculateService.calculate method from Flash CS3 using Strippers Remoting Classes. †This example uses Strippers Remoting Classes. import jp.strippers.remoting.*;
import flash.net.Responder;
var gatewayUrl:String = "http://127.0.0.1/gateway/";
var serviceName:String = "calculateService";
var serviceFactory:ServiceFactory = ServiceFactory.getInstance(gatewayUrl);
var service:RemotingService = serviceFactory.getService(serviceName);
// service.connection.setCredentials("username", "password"); // If authentication is necessary
var pc:PendingCall = service.calculate(2, 3);
pc.responder = new Responder(handleResult, handleError);
function handleError(result:int):void {
trace("Result is" + result);
}
function onFault(fault:Object):void {
trace(fault.faultstring);
}
Example of calling calculateService.calculate method from Flash 8. †This example uses Flash Remoting Components. import mx.remoting.*;
import mx.rpc.*;
var gatewayUrl:String = "http://127.0.0.1/gateway/";
var serviceName:String = "calculateService";
var service:Service = new Service(gatewayUrl, null, serviceName, null, null);
var pc:PendingCall = service.calculate(2, 3);
pc.responder = new RelayResponder(this, "handleResult", "handleError");
function handleResult(re:ResultEvent):Void {
trace("Result is" + re.result);
}
function handleError(fe:FaultEvent):Void {
trace(fe.fault.faultstring);
}
Example of calling calculateService.calculate method from Flex2 using S2Flex2-components †This example uses S2Flex2-components. <?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:s2="http://www.seasar.org/s2flex2/mxml"
layout="absolute"
applicationComplete="doCalculate()">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
import mx.rpc.AsyncToken;
private function doCalculate():void {
var token:AsyncToken = service.calculate(2, 3);
token.resultHandler = handleResult;
token.faultHandler = handleFault;
}
private function handleResult(re:ResultEvent):void {
Alert.show("Result is " + re.result);
}
private function handleError(fe:FaultEvent):void {
Alert.show(fe.fault.faultDetail);
}
]]>
</mx:Script>
<s2:RemoteService
id="service"
gatewayUrl="http://127.0.0.1/gateway/"
destination="calculateService"
useAMF0="false"
result="event.token.resultHandler(event)"
fault="event.token.faultHandler(event)"
showBusyCursor="true" />
</mx:Application>
If you would like to use AMF3, 'useAMF0' attribute of <s2:RemoteService> has to be set 'false'. Custom Class Mapping †Custom Class Mapping maps ActionScript class(AS class) to Python class each other, and converts the object sent from/to remoting serivce into the mapped class object automatically. There are two ways of defining custom class mappings:
Each way is explained below. Here, suppose that AS class 'com.example.CustomerDto' is mapped to python class 'example.models.Customer'. Specify python class name in Flash/Flex applicaiton †Before invoking remoting service method, execute the following code.
Make AMF_CLASS_MAPPER module †Execute Object.registerClass() or registerClassAlias() method as explained above. But you can set arbitrary name instead of "Python class name". import flash.net.*;
registerClassAlias("customer", com.example.CustomerDto);
Then, define a function named 'amf_class_mappings' in a python module you like. The function must returns dict object holding mapping information: Key is the arbirary name set in Flash/Flex, Value is python class name. For example, define the funciton in exmple.views module (example/views.py), def amf_class_mappings():
return { "customer" : "example.models.Customer" }
then add AMF_CLASS_MAPPER variable in settings.py. AMF_CLASS_MAPPER = 'example.views' If the mapped class information or the mapped class itself is not found, the sent object is treated as dict type in python and as Object type in Flash/Flex. Session †If sessions enabled in Django, a session object in HTTPRequest can be used in view function. Authentication †There are two ways to implement authentication system.
Defining custom authentication function †First of all, permission names to be used for user authentication are required. As an example, this document uses two permissions, "user" and "admin".
This views.py has three functions, one which does not require any permission, one which the users holding "user" permission can invoke, and which the users holding "admin" permission can invoke. @permission_required('permission')
Add the decorator above to the view functions which require user authentication. @permission_required('permission1, permission2, ...')
Next, you need to make a function to determine users' permissions. You can make this function in an arbitrary module. In this document, add the function to example/views.py.
The function for authentication must have three arguments. The first one is Request object, the second one is username of the user, and the third one is password of the user. The above example returns "user" permission if username is "foo" and password is "bar". Real applications will use a database to get users' permissions. Lastly, define this function name as the authentication function in settings.py.
Then, the view functions with @permission_required decorator can be invoked only by the user who has the specified permission. Set username and password in ActionScript †If using S2Flex2-components in Flex2, use setCredentials method of RemoteService instance. removetService.setCredentials('username', 'password');
example private function doCalculate():void {
service.setCredentials('foo', 'bar'); // Set username and password
var token:AsyncToken = service.calculate(2, 3);
token.resultHandler = handleResult;
token.faultHandler = handleFault;
}
Using Django's authentication system †Django comes with a user authentication system. It can be integrated into Django AMF. Refer to the document page above for Django's authentication system and its configurations. Using Django's authentication system, you do not need to make the function for authentication.
That's all for authentication. To create custom permissions like "user" and "admin", refere to http://docs.djangoproject.com/en/dev/topics/auth/#id1 |