views:

83

answers:

1

I have an AppEngine app that I'm migrating to run in Django, using app-engine-patch to get all the goodness of Django - particularly the Admin interface.

One of my models looks like (partially) this:

class Request(db.Model):
  requestor = db.UserProperty(auto_current_user_add=True)

When I display a form based on this model I don't display the requestor field, and so when I call the Model's put() method the entity I'm saving doesn't have the requestor property set. This triggers the auto_current_user_add magic, and the user who created the request is automatically added.

Under Django, I'm using the provided Users table. I want this to display as a list of the users of my app, so the model becomes:

from ragendja.auth.google_models import User

class Request(db.Model):
  requestor = db.ReferenceProperty(User)

However, this breaks the auto_current_user_add magic in the admin interface - if the user of the admin interface doesn't enter a value for the requestor property, Django sets the property to None, when I'd really like for the Request to have their username inserted automatically.

How can I restore the magic?

A: 

My solutions relies on three things:

  • First: it's possible to override the model's put() method.
  • Second: users.get_current_user() still provides the correct user, and
  • Third: ragendja.auth.google_models.User.get_djangouser_for_user() takes a google.appengine.api.users.user object and returns the corresponding Django User object - creating it first if it didn't already exist.

Putting this all together, I have:

class Request(db.Model):                                                                                           
  requestor = db.ReferenceProperty(User)

  def put(self):
    if not self.requestor:
      self.requestor = User.get_djangouser_for_user(users.get_current_user())
    super(Request, self).put()

This works nicely with the admin interface: the admin can assign any existing user (or use the supplied + sign to create a new user) - if they leave it blank, they'll be assigned as the requestor.

Later when I add a view for users to manage their own requests, this value will be on the 'excluded' list, and the same method will add in their username every time they create a new request.

I'm not sure if this is an optimal solution though; I'm new to Django, so maybe there's a better way to achieve this.

James Polley