views:

930

answers:

3

Hey there,

I'm using PyAmf to communicate with a Flex app. But I keep getting errors.

My model:

from django.contrib.auth.models import User

class Talent(User):
    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)

My gateway file:

from pyamf.remoting.gateway.django import DjangoGateway
from addestino.bot.services import user
from addestino.bot.models import *
from django.contrib.auth.models import User
import pyamf

pyamf.register_class(User, 'django.contrib.auth.models.User')
pyamf.register_class(Talent, 'addestino.bot.models.Talent')

services = {
    'user.register': user.register,
    'user.login': user.login,
    'user.logout': user.logout,
}

gateway = DjangoGateway(services, expose_request=True)

The Flex Talent object:

package be.addestino.battleoftalents.model
{
    [Bindable]
    public class Investor
    {
    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()
    {
    }      
}

}

If Flex calls my register servicemethod (a method that sends a flex Investor to python), I get an error 'KeyError: first_name'. Then when we add a first_name field to our Flex VO, we get a last_name error. And so on. This error means that our flex VO has to have exactly the same fields as our django models. With simple objects this wouldn't be a problem. But we use subclasses of the django User object. And that means our Investor also needs a user_ptr field for example. Note: I get all errors before the servicemethod.

Is there an easier way? Ideally we would have a Flex Investor VO with only the fields that we use (whether they're from the Django User or our django Investor that extends from User). But right now the Flex objects would have to be modeled EXACTLY after our Django objects. I don't even know exactly what the Django User object looks like (which I shouldn't).

I could really use some help. Thanks a lot in advance :-)

+1  A: 

This is done using the IExternalizable interface.

It lets you explicitly write and read objects. If this is similar to Java implicit serialization, it's not going to let you limit what is sent by default. I was unable to find any examples of this with PyAMF.

Best post on Serialization I've found.

Brandon
A: 

Joske, I'm having the same problem with PyAMF and I'm sorry to say I haven't found a solution yet. The PyAMF gang has an irc channel (they are helpful!) have you asked there, they help me plenty, but I'm stuck with this one.

Anyway can you have the Talent class as a foreingkey to user, or adding as UserProfile (see http://www.b-list.org/weblog/2006/jun/06/django-tips-extending-user-model/)

PyAMF has no problems sending objects related with foreignkey using .select_related(). I've been using for a while now.

If you find a way out... please edit. Any updates all edit my answer.

Cheers, Ale.

Ale
A: 

With the release of PyAMF 0.6b2 I can finally answer this question.

0.5.1 was pretty strict in how it handled inheritance when it came to encoding Django models. It ensured that all properties were guaranteed to be encoded on each object - and expected that all properties were available when decoding the request.

This sucked and the behaviour has now changed with the release of the new version. PyAMF is a lot more forgiving about what you hand it from Flex. You shouldn't get the KeyError error any more (and if you do, its considered a bug).

njoyce