'Django: how to keep track of order for items of a model

I have a model:

class Recipe(models.Model):
     name=models.CharField()

class Ingredients(models.Model):
     name=models.CharField()


class RecipeIngredients(models.Model):
     recipe=models.ForeignField(Recipe)
     ingredients = models.ForeignField(Ingredients)

I am creating RecipeIngredients, but i want to show them in a sequence

Sometime i have to add an ingredient inbetween. So in such cases how to keep the order while getting them



Solution 1:[1]

I just stumbled on the same problem in my own project, but couldn't find a good answer on stackoverflow.

My solution was to use Recipe and Ingredient models, and include an 'order' field in the Ingredient model. That way you can track the order in which you'd like the ingredients to appear. I also added a modified field which is useful for the second half of this solution.

class Recipe(models.Model):
    name=models.CharField()

class Ingredient(models.Model):
    name=models.CharField()
    recipe=models.ForeignKey('Recipe', blank=True, null=True, on_delete=SET_NULL)
    order=models.SmallIntegerField(default=-1)
    modified=models.DateTimeField(auto_now=True)

I then added the following to signals to handle when a new ingredient is added.

@receiver(pre_save, sender=Ingredient)
def pre_ingredient_save(sender, instance, *args, **kwargs):

    if instance.order == -1:
        count = sender.objects.filter(recipe=instance.recipe).aggregate(Max('order'))['order__max']
        instance.order = count + 1

@receiver(post_save, sender=Ingredient)
def post_ingredient_save(sender, instance, *args, **kwargs):

    ingredients = sender.objects.filter(recipe=instance.recipe).order_by('order', '-modified')
    counter = 1
    for ingredient in ingredients:
        ingredient.filter(id=ingredient.id).update(order=counter)
        counter +=1

The pre save signal handles ingredients that are added without their order specified (it just adds it to the end of the list of ingredients). The post save signal handles ingredients which are given a specific order when created and slots them into the correct position.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Andrew Einhorn