views:

111

answers:

1

For example, using my UserProfile model:

class UserProfile(models.Model):
  user      = models.ForeignKey( User, unique=True )
  blurb     = models.CharField( max_length=200, null=True, blank=True )
  public    = models.BooleanField( default=True )
  ...

Thus, I end up with a field called "public". This doesn't jive in ActionScript because it's a keyword. It's annoying to change because it's baked into several layers of functionality in the django-profile package. So, I'm forced to rename it on the Flex side:

[RemoteClass(alias="...")]
[Bindable]
public class UserProfile
{
    public function UserProfile()
    {
    }
    public var id:int;
    public var blurb:String;
    public var _public:Boolean;
    ...

Where, on either side of the transaction, can I state "remote field public translates to local field _public"? I messed around a bit with ClassAliases on the PyAMF side but it got messy quickly and there's no documentation on how to do this nicely. And the documentation on the Flex side seems to indicate that there's a "process the incoming request" handler that I can override, but I think it occurs after already populating the fields in the com object, thus dropping them on the floor, since the appropriate field is not there, and leaving me with a bunch of:

ReferenceError: Error #1056: Cannot create property

in the Flex trace...

+1  A: 

In order to support this, PyAMF needs to provide a synonym mapping between fields. Until then, you could use IExternalizable (although clumsily):

class UserProfile(model.Model):
  user      = models.ForeignKey( User, unique=True )
  blurb     = models.CharField( max_length=200, null=True, blank=True )
  public    = models.BooleanField( default=True )

  class __amf__:
    external = True

  def __writeamf__(self, output):
    output.writeObject(self.id)
    output.writeObject(self.blurb)
    output.writeObject(self.public)

  def __readamf__(self, input):
    self.id = input.readObject()
    self.blurb = input.readObject()
    self.public = input.readObject()

With the corresponding Flex code:

[RemoteClass(alias="...")]
[Bindable]
public class UserProfile implements IExternalizable
{
  public function UserProfile()
  {
  }
  public var id:int;
  public var blurb:String;
  public var _public:Boolean;

  public function writeExternal(output:IDataOutput)
  {
    output.writeObject(id);
    output.writeObject(blurb);
    output.writeObject(_public);
  }

  public function readExternal(input:IDataInput)
  {
    id = input.readObject();
    blurb = input.readObject();
    _public = input.readObject();
  }
}

Note I haven't tested the above code, but should work in principle.

Btw, can you go into greater detail about what was confusing about the documentation? I would love to make that as clear possible for new users.

njoyce
awesome, thank you so much, i'm sure this should work, i'll try it out shortly. to be fair, i did see something to this effect written someplace, i was just hoping that there would be something more explicit that would write this for me, so that i wouldn't have to keep doing it in the future. however, i guess i could write the wrapper for this and post it for others to use. :-)to answer your request, i'd say that giving what you wrote above as an example in the documentation link you pointed to would have helped - i had to dig elsewhere to get something similar to the above.
eruciform
also, the above has the flavor of being a bit of a hack, or skirting under the hood, to me. it doesn't give me confidence that it's not going to break something elsewhere. whereas a specific api that maps one field to another would. however, that's just the feeling i get from typing so many __ double-underscore __ things that include hard-coded-ordered information. (feels like packing tcp by hand or something :-)it would also be nice if there were more of an explanation of the classalias interface. i'm not really sure what it does, after having read the documentation, or how to use it.
eruciform
ClassAlias is meant to be an internal class to PyAMF that is used to process the metadata that [class].__amf__ provides. The above answer is indeed a hack and I have created a ticket provide the synonym facility described. See http://dev.pyamf.org/ticket/779
njoyce
very nice, thank you! i'm happy to see someone taking the opportunity to put a solution back into the product!
eruciform
Related to the above: http://stackoverflow.com/questions/3182738/pyamf-0-6-doesnt-seem-to-encode-django-1-2-foreignkey-related-objects-proper
eruciform