How do I order referenced objects from a Google App Engine Datastore query?
-
22-08-2019 - |
Question
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.
Solution
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.