I have read this question and the simple and clear answer but it's not useful in my case because the answer don't consider the nested for
. please, see the code:
class SuperCat(ndb.Model):
class Category(ndb.Model):
supercat = ndb.KeyProperty(kind=SuperCat)
class SubCat(ndb.Model):
category = ndb.KeyProperty(kind=Category)
handler:
Categories = ndb.gql("SELECT * FROM Category WHERE supercat = :1", supercat_key)
self.generate('supercat.html', {'Categories': Categories})
in template, with the old db.Model and the back-reference property this is enough:
{{ for Category in Categories }}
{{ for SubCat in Category.subcat_set }} # this is the back-reference in action
What is the equally simple alternative to serve such data structure?
Let's look at this systematically. First, the db->ndb translation guide tells us that the query returning SubCategory instances for a given Category instance is as follows:
subcats_query = SubCategory.query(SubCategory.category == cat.key)
(Note that I use lowercase names for instances/entities and CapWords for classes/models. So cat is a Category entity.)
So in Python, we would write your double loop as follows:
for cat in categories:
for subcat in SubCat.query(SubCat.category == cat.key):
...blah...
In order to turn this into something that's easily accessible from the template, let's define a new method on the Category class:
class Category(ndb.Model):
supercat = ndb.KeyProperty(kind=SuperCat)
def subcat_set(self):
return SubCat.query(SubCat.category == self.key)
Note that this is a method; in Python, you have to call it:
for cat in categories:
for subcat in cat.subcat_set():
...blah...
But in a template you can (must) leave out the () call syntax, so you get what you want:
{{ for cat in categories }}
{{ for subcat in cat.subcat_set }}
...blah...
Give it a try!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With