1

Update

This was my best effort creating the following scheme enter image description here

user = self.auth.store.user_model.create_user(email,
        password_raw=newpasswd)
if not user[0]:  # user is a tuple
    return user[1]  # Error message
else:

    # User is created, let's try making the references
    okuser = auth_models.User.get_by_id(long(user[1].key.id()))
    okuser.sponsor = auth_models.User.get_by_id(long(sponsor_id)).auth_ids

Original question

How can I make a selfreference with an expando class to indicate which User is the "sponsor" of which? The "sponsor" is the one who invited the new User so at creation we must store that and it would be much neater to store it as a referenceproperty than a string or a stringlist.

I can create a new user but I don't know how to make a reference so that I can tell for one User who another User is who is the sponsor of the first user and I suppose a way to model this is with selfreferenceproperty since both objects are users but the complication is that it is an expando model so I don't know how to use the reference property. Could you tell me how to do it or give me a clue how I can solve this problem in the best way?

user = self.auth.store.user_model.create_user(email,
        password_raw=newpasswd)
if not user[0]:  # user is a tuple
    return user[1]  # Error message
else:

    # User is created, let's try making the reference
    okuser = auth_models.User.get_by_id(user[1].key.id())
okuser.sponsor = db.SelfReferenceProperty(User,
    collection_name='matched_images', verbose_name='Sponsor')

I don't know how to do the last part, to store the actual referenceproperty with an epando model. How can it be done?

Update

It seems it can't be done:

NotImplementedError: Property sponsor does not support <class 'google.appengine.ext.db.ReferenceProperty'> types.

Code:

user = self.auth.store.user_model.create_user(email,
        password_raw=newpasswd)
if not user[0]:  # user is a tuple
    return user[1]  # Error message
else:

    # User is created, let's try redirecting to login page
    okuser = auth_models.User.get_by_id(long(user[1].key.id()))
    okuser.sponsor = db.SelfReferenceProperty(auth_models.User.get_by_id(sponsor_id),collection_name='matched_distributor')
    okuser.put()

It forces me do use a string instead of a reference and then a solution is feasible:

user = self.auth.store.user_model.create_user(email,
        password_raw=newpasswd)
if not user[0]:  # user is a tuple
    return user[1]  # Error message
else:

    # User is created, let's try redirecting to login page
    okuser = auth_models.User.get_by_id(long(user[1].key.id()))
    okuser.sponsor =  sponsor_id
    okuser.put()
Nick Johnson
  • 100,655
  • 16
  • 128
  • 198
Niklas Rosencrantz
  • 25,640
  • 75
  • 229
  • 424

1 Answers1

1

You can't assign an instance of a Property class to an instance of a model - property classes define properties, they don't represent individual values.

By far the easiest way to do what you want is to add the property as you would on a regular model. Just because you're using expandos (why, by the way?) doesn't mean you can't have regular properties on them as well.

Nick Johnson
  • 100,655
  • 16
  • 128
  • 198
  • I wanted something like a selfreference and I had to use ndb keyproperty and the user model from webapp2 has only expando fields and I didn't want to modify a file that is not my project. So I have third-party user model but now I added a required property when I couldn't even use FilterNode because of some bug in ndb with expando models. It's natural to my model that every user has a sponsor so I just added the variable `sponsor = KeyProperty()` and then I can use it like a relation / reference. – Niklas Rosencrantz Jan 09 '12 at 16:32
  • Note that the simplest way to do this might be extend webapp2's user model by creating your own User class inheriting from `webapp2_extras.appengine.auth.models.User` and adding the desired properties. – Alex Pretzlav Feb 28 '12 at 03:37