Home > OS >  Best Django method for multiple entries for the same field
Best Django method for multiple entries for the same field

Time:06-09

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()
  • Related