App Engine Datastore API – Tutorial 2

Posted: October 15th, 2009 | Author: Giv | Filed under: Python, Tutorials | No Comments »

In the last tutorial we quickly created a couple of models for storing our recipes and ingredients. In this tutorial we are going to assign ingredients to recipes as a one-to-many relationship.

But before we do that, we need to modify our data models a bit. The Recipe model stays the same but we’ll need a way of referencing the ingredients to add them to a single recipe. Like an SQL foreign key. We can do this using the “ReferenceProperty”:

1
2
3
4
class Ingredient(db.Model):
    name = db.StringProperty()
    recipe = db.ReferenceProperty(Recipe, collection_name='recipe_items')
    created = db.DateTimeProperty(auto_now_add=True)

The recipe ReferenceProperty allows us to associate Recipe objects to ingredients. Creating this relationship is straight forward:

1
2
3
4
5
6
7
# first create a recipe
recipe = Recipe(title = "Caprese Salad", description = "Light Italian classic").put()
 
# now create 3 ingredients and add them to the recipe object
Ingredient(recipe=recipe, name='Tomato').put()
Ingredient(recipe=recipe, name='Mozzarella').put()
Ingredient(recipe=recipe, name='Basil').put()

We just created 4 entries, 1 recipe and 3 ingredients. We can query them individually:

1
2
recipes = Recipe.all()
ingredients = Ingredient.all()

Except we’ve created a relationship between these entries so we can loop through all of our recipes and for each check to see if there are any associated ingredients. We can do this by using the collection_name we specified in our Ingredient model (“recipe_items”). So we can just get back a list of our recipes and send the whole list to the view like we did last time:

1
2
3
4
5
6
recipes = Recipe.all()
recipes.order("title")
recipeResults = recipes.fetch(limit=40)
 
# again, I'm just using Django templates
return render_to_response('main/index.html', {'recipeResults': recipeResults})

We don’t need to perform a separate query in the controller to get back the ingredients. All associated ingredient recipes are referenced so we can access them directly in the view:

1
2
3
4
5
6
7
8
9
10
11
<ul>
    {% for recipe in recipeResults %}
        <li>			
            {{ recipe.title }} 
#now for each recipe we'll loop through its associated ingredients
               ({% for ing in recipe.recipe_items %}
                   {{ ing.name }},
               {% endfor %})
        </li>
    {% endfor %}
</ul>

If you want to go further, I recommend checking out the modeling entity relationship docs. There are plenty of great examples.

Share
  • Twitter
  • Facebook
  • Digg
  • del.icio.us
  • Google Bookmarks
No Comments »

Leave a Reply