views:

78

answers:

1

Hay guys, I'm writing a simple app which logs recipes.

I'm working out my models and have stumbled across a problem

My Dish models needs to have many Ingredients. This is no problem because i would do something like this

ingredients = models.ManyToManyfield(Ingredient)

No problems, my dish now can have many ingrendients.

However, the problem is that the ingredient needs to come in different quantities.

I.E 4 eggs, 7 tablespoons sugar

My Ingredient Model is very simple at the moment

class Ingredient(models.Model):
    name = models.TextField(blank=False)
    slug = models.SlugField(blank=True)

How would i go about work out this problem? What fields would i need to add, would i need to use a 'through' attribute on my ManyToManyfield to solve this problem?

+1  A: 

Hey dotty,

I think you got the right answer with a "through" table ( http://docs.djangoproject.com/en/dev/topics/db/models/#intermediary-manytomany )

Model

class Recipe(models.Model):
    name = models.TextField(blank=False)
    ingredients = models.ManyToManyField(Ingredient, through='Components')

class Ingredient(models.Model):
    name = models.TextField(blank=False)
    slug = models.SlugField(blank=True)

class Components(models.Model):
    recipe = models.ForeignKey(Recipe)
    ingredient = models.ForeignKey(Ingredient)
    quantity = models.DecimalField()

You can put unit of quantity (gram, kilo, tablespoon, etc) on Ingredient level, but I think it is better on Ingredients level (for example you can have 1 recipe with 10 Cl of milk but one other with 1L ... So "different" units for a same ingredient.

Data Creation

By Dish you mean Recipe right ? If you have a look to previous link (http://docs.djangoproject.com/en/dev/topics/db/models/#intermediary-manytomany), they give you a good example (based on the beatles). Basically :

1.Create a Recipe:

cake=Recipe.objects.create(name="Simple Cake")

2.Create several Ingredient (if they doesn't already exist from a previous recipe ;)):

egg = Ingredient.objects.create(name="Egg")
milk = Ingredient.objects.create(name="milk")

3.Create the relationship:

cake_ing1 = Components.objects.create(recipe=cake, ingredient=egg,quantity = 2)  
cake_ing2 = Components.objects.create(recipe=cake, ingredient=milk,quantity = 200)

and so on. Plus, I'm now quite sure that unit should go to Components level, with a default unit as "piece" (that would be for yours eggs ...), and would be something like "mL" for milk.

Data Access

In order to get ingredients (Components) of a recipe just do :

cake = Recipe.objects.get(name = "Simple Cake")
components_cake = Components.objects.get(recipe = cake)
Olivier Rochaix
How would i add another ingredient after the initial Dish object has been created?
dotty
My Ingredients model is called Components and looks pretty much the same as that model. I want to create a Dish Obj, then add lots of Ingrentients. Usually i would do Dish.ingredients.add(Ingredient Obj), but i need these extra fields. Would i create a Component object and then do Dish.ingredients.add(Component Obj) ?
dotty
I just add more informations in my former post (because not enough space in comment !)
Olivier Rochaix
ok thats all fine, i can now add more ingredients to a dish (recipe). Now when i do Dish.ingredients.all() . cannot access the Components properties. So i cannot do Dish.ingredients.all()[0].quantity because it just returns a ingredient obj, not a component obj.
dotty
Any ideas on the above question?
dotty
I add some comments about how to access data, hope it helps !
Olivier Rochaix
So how is it going ?
Olivier Rochaix