1、问题背景
PyAMF 是一个用于在 Flex 和 Python 之间进行通信的库,在使用 PyAMF 与 Flex 应用进行通信时,经常会遇到错误。例如,在发送一个 Flex Investor 对象到 Python 时,会得到一个 ‘KeyError: first_name’ 的错误。这是因为 Flex 对象必须与 Django 模型具有完全相同的字段,否则就会出错。
2、解决方案
为了解决这个问题,可以使用 IExternalizable 接口。IExternalizable 接口允许您显式地写入和读取对象。通过使用 IExternalizable 接口,可以只发送和接收 Flex 对象中需要使用的字段,而无需发送所有字段。
在 PyAMF 0.6b2 版本中,对继承处理进行了修改,现在 PyAMF 对从 Flex 传入的对象更加宽容。您应该不会再收到 KeyError 错误了。
以下是使用 IExternalizable 接口来解决问题的示例代码:
from django.contrib.auth.models import User
from pyamf.flex import *
class Talent(User, IExternalizable):
street = models.CharField(max_length=100)
street_nr = models.CharField(max_length=100)
postal_code = models.PositiveIntegerField()
city = models.CharField(max_length=100)
description = models.CharField(max_length=100)
def __externalize__(self):
return {
'id': self.id,
'username': self.username,
'first_name': self.first_name,
'last_name': self.last_name,
'email': self.email,
'street': self.street,
'street_nr': self.street_nr,
'postal_code': self.postal_code,
'city': self.city,
'description': self.description,
}
@classmethod
def __internalize__(cls, data):
talent = cls(**data)
return talent
```python
在 Flex 端,可以使用以下代码来注册 IExternalizable 类:
```python
[Bindable]
public class Investor extends Externalizable {
public static var ALIAS:String = "be.addestino.battleoftalents.model.Investor";
public var id:Object;
public var street:String;
public var street_nr:String;
public var postal_code:uint;
public var city:String;
public var cash:Number;
public var date_created:Date;
public var date_modified:Date;
public var username:String;
public var password:String;
public var email:String;
public function Investor() {
}
override public function writeExternal(output:IExternalizable):void {
super.writeExternal(output);
output.writeObject(id);
output.writeUTF(street);
output.writeUTF(street_nr);
output.writeUInt(postal_code);
output.writeUTF(city);
output.writeNumber(cash);
output.writeObject(date_created);
output.writeObject(date_modified);
output.writeUTF(username);
output.writeUTF(password);
output.writeUTF(email);
}
override public function readExternal(input:IExternalizable):void {
super.readExternal(input);
id = input.readObject();
street = input.readUTF();
street_nr = input.readUTF();
postal_code = input.readUInt();
city = input.readUTF();
cash = input.readNumber();
date_created = input.readObject() as Date;
date_modified = input.readObject() as Date;
username = input.readUTF();
password = input.readUTF();
email = input.readUTF();
}
}
使用 IExternalizable 接口可以解决 Flex 类映射的问题,从而实现 PyAMF 与 Flex 应用的无缝通信。