I am trying to figure out the best method to add multiple instances of the same field for a Recipe class I have created.
When creating the new Recipe, I need to be able to add multiple instances of Ingredient, Measurement Unit, Unit Value. For example:
ingredient = Lemon
measurement_unit = ml
unit_value = 100
I would then need to add another Ingredient and do the exact same thing. I would then be able to save the Recipe.
What would be the best method to use to achieve this?
CodePudding user response:
I would create a model for Ingredient and then set a many to many relationship between ingredients and recipes.
Like This:
class Ingredient(models.Model):
name = models.CharField(max_length=150, unique=True)
measurement_unit = models.CharField(max_length=150, unique=True)
unit_value = models.IntegerField()
recipe = models.ManyToManyField(Recipe)
Then from any recipe you could access all the ingredients.
CodePudding user response:
I don't know about the best, but the obvious one is a RecipeIngredient
model.
This is a bit more complex than Scrolen's suggestion, but allows multiple recipes to use different amounts of the same ingredient. This becomes useful if there is a fair bit of information you need to attach to an ingredient. Things like supplier, sub-ingredients, allergens, nutritional info, ... you can edit the ingredient, and all the recipes that use it immediately have updated ingredient information.
class Recipe( models.Model):
name = models.CharField( ...)
status = models.CharField( choices = STATUS_CHOICES, ...)
...
class Ingredient( models.Model):
name = models.CharField( unique=True, ...)
...
class RecipeIngredient( models.Model):
recipe = models.ForeignKey( Recipe, models.PROTECT, related_name='ingredients', ...)
ingredient = models.ForeignKey( Ingredient, models.PROTECT, ...)
unit = models.CharField( choices=UNIT_CHOICES, ...)
value = models.FloatField( ...)
usage:
recipe = Recipe( name = 'Lemon Cheesecake', status=Recipe.ON_HOLD )
recipe.save()
# ON_HOLD stops anybody using a recipe only half populated with ingredients
ingredient = Ingredient.objects.get( name='lemon juice')
item = RecipeIngredient(
ingredient=ingredient,
recipe = recipe,
unit='ml',
value=100 )
item.save()
# repeat until all the ingredients are attached to the recipe
# and other stuff such as instructions are also filled in
recipe.status = Recipe.READY
recipe.save()
# now it's ready for somebody to try to cook it!
To get the list:
recipe = Recipe.objects.get( name = 'Lemon Cheesecake')
for item in recipe.ingerdients.all():
item.ingredient.field ... # refers to data in the related Ingredient
item.unit
item.value
CodePudding user response:
It seems like Foodgram project from YP:))
In my Foodgram i have used through
option for ManyToManyField and i think it`s optimal. https://docs.djangoproject.com/en/4.0/ref/models/fields/#django.db.models.ManyToManyField.through. It clearly explained in django docs.
You can write something like this:
class Recipe(models.Model):
name = models.CharField(...)
...
ingredients = models.ManyToManyField(
Ingredient,
through=RecipeIngredient,
...
)
class Ingredient(models.Model):
name = models.CharField(...)
measurement_unit = models.CharField(...)
...
class RecipeIngredient(models.Model):
ingredient = models.ForeignKey(Ingredient, on_delete=models.CASCADE)
recipe = models.ForeignKey(
Recipe,
related_name='recipeingredients',
on_delete=models.CASCADE
)
amount = models.FloatField()