views:

265

answers:

1

I have Exhibit objects which reference Gallery objects both of which are stored in the Google App Engine Datastore.

How do I order the Exhibit collection on each Gallery object when I get around to iterating over the values (ultimately in a Django template)?

i.e. this does not work


class Gallery(db.Model):
  title = db.StringProperty()
  position = db.IntegerProperty()

class Exhibit(db.Model):
  gallery = db.ReferenceProperty(Gallery, collection_name='exhibits')
  title = db.StringProperty()
  position = db.IntegerProperty()

galleries = db.GqlQuery('SELECT * FROM Gallery ORDER BY position')
for gallery in galleries:
  gallery.exhibits.order('position')

# ... send galleries off the the Django template

When rendered in the template, the galleries are correctly ordered but the exhibits are not.

+4  A: 

Instead of relying on the collection property App Engine creates, you need to construct your own query:

exhibits = Exhibit.all().filter("gallery =", gallery).order("position")

Or equivalently, in GQL:

exhibits = db.GqlQuery("SELECT * FROM Exhibit WHERE gallery = :1 ORDER BY position", gallery)

If you want to be able to do this from inside the template, rather than passing in a list-of-lists of exhibits, you can define a simple method on the Gallery object that executes this query, and reference it from the template (Eg, {{gallery.exhibits_by_position}} will execute exhibits_by_position() on the Gallery object, which can then perform the query above).

If you're concerned about the speed implications of this, don't worry: The collection property App Engine creates is simply syntactic sugar for this.

Nick Johnson
I hadn't thought about using a method, works great thanks!
Brendan