Display data from foreign key

Hello,

I am building an app to manage fresh food stores such as bakeries, pastry shops, deli counters…

I have the following models:

models.py

= models.CharField(max_length=60, unique=False, verbose_name=‘nom’)
category = models.ForeignKey(IngredientCategory, on_delete=models.CASCADE, verbose_name=‘catégorie’)
supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE, verbose_name=‘fournisseur’)
supplier_item_number = models.CharField(max_length=20, blank=True, verbose_name=‘n° article fournisseur’)
supplier_item_name = models.CharField(max_length=30, blank=True, verbose_name=‘nom article fournisseur’)
ean13 = models.DecimalField(max_digits=13, decimal_places=0, blank=True, null=True)
purchase_unit = models.CharField(max_length=6, choices=UNIT, verbose_name=“unité d’achat”)
use_unit = models.CharField(max_length=6, choices=UNIT, verbose_name=“unité d’utilisation”)
stock_unit = models.CharField(max_length=6, choices=UNIT, verbose_name=“unité de stockage”)
invoiced_price = models.DecimalField(max_digits=7, decimal_places=3, verbose_name=‘prix facturé’)
net_weight = models.DecimalField(max_digits=6, decimal_places=3, blank=True,
verbose_name=‘poids net ou volume unitaire’)
number_of_packs_per_purchase_unit = models.DecimalField(max_digits=3, decimal_places=0,
verbose_name=‘nombre de paquets par colis’,
default=1,
help_text=‘nombre de pièces par carton’)
number_of_number_pieces_per_pack = models.DecimalField(max_digits=3, decimal_places=0, default=1,
verbose_name=‘nombre de pièces par paquet’,
help_text=‘nombre de pièce par paquet’)
ingredient_yield = models.DecimalField(max_digits=3, decimal_places=2, default=1, verbose_name=‘rendement’,
help_text=‘ex: pour 93% mettre 0.93’)

class Production(models.Model):
“”“used to create a production number in order to insure traçability”“”
production_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=60, blank=True, null=True, verbose_name=‘nom’)
date = models.DateField(blank=True, null=True)

def __str__(self):
    return 'lot n° {} {}'.format(self.production_id, self.name)

lass Recipe(models.Model):
“”“gives a name and describes the recipe and calculate its cost”“”

recipe_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=60, verbose_name='nom')
recipe_category = models.ForeignKey(RecipeCategory, on_delete=models.CASCADE, verbose_name="type de recette")
recipe_steps = models.TextField(max_length=2000, verbose_name='mode opératoire')
recipe_yield = models.DecimalField(max_digits=3, decimal_places=2, verbose_name='rendement', default=1,
                                   help_text='ex: pour 93% mettre 0.93')
number_of_serving = models.IntegerField(default=1, verbose_name="nombre de parts, tranches...")
UNIT_CHOICES = [("kg", "kg"), ("litre", "litre"), ("piece", "pièce")]
unit = models.CharField(max_length=6, choices=UNIT_CHOICES, default='kg', verbose_name='unité')

class RecipeIngredient(models.Model):
recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE, verbose_name=‘recette’)
ingredient = models.ForeignKey(Ingredient, on_delete=models.CASCADE)
quantity = models.DecimalField(max_digits=6, decimal_places=3, verbose_name=‘quantité’)
unit = models.CharField(max_length=10, editable=False, null=True, blank=True, verbose_name=‘unité’)

# nested in lines
ingredient_price = models.DecimalField(max_digits=6, decimal_places=3, blank=True, null=True,
                                       verbose_name="prix total de l'ingrédient")
quantity_per_serving = models.DecimalField(max_digits=6, decimal_places=3, blank=True, null=True,
                                           verbose_name="quantité d'ingrédient par part servie")
price_per_serving = models.DecimalField(max_digits=6, decimal_places=3, blank=True, null=True,
                                        verbose_name="prix de l'ingrédient par part servie")
production = models.ForeignKey(Production, on_delete=models.CASCADE, blank=True, null=True, editable=False)

To explain a bit my purpose:
I have Ingredients that I use in Recipes.
In Production I can set to produce several Recipes.
What I need is to to display all the ingredients (and there quantities) in order to be able to purchase them according to my needs.

All my calculations are done in the models and I am using only the admin interface

When entering code into the body of your message, surround your code by lines of three backtick - ` characters. This means that you’ll have a line of ```, then your code, then another line of ```. This forces the forum software to keep your code properly formatted.

You don’t need to repost the code, you can edit your original code to put the ``` before and after each file’s code. (Note, the lines of ``` must be lines by themselves, they must not be parts of other lines.)

It would also help if you could be a little more specific about what you’d like to see. You mention you want to see “all the ingredients and their quantities”. Where do you want to see this information? What are you wanting it to look like?

Ken,

thanks a lot for your advices as it is my first post on the forum.
I would like to have some spreadsheet or printable page with all the ingredients I need in order to be able to produce what I need
for example I can produce:

  • a batch of chocolate mousse which use eggs, sugar and chocolate
  • two batches of pancake that use eggs
  • 5 batch of cookies who will use eggs, chocolate and sugar + other ingredients.
    I want a list of all the ingredients + the quantities I need to launch my production.
    I will manage after to filter by suppliers in order to have a ready email to order my ingredients according to my production needs
    Thanks in advance

Not a problem - we’re glad you’re here and are happy to help.

The admin is not going to be your facility for doing that. You’re going to want to create a view to produce your desired output.

Ken,
thanks a lot for your answer, I am going to do that.

Best regards

Guillaume

Hello Ken,

I am trying but I am not able to retrieve the data. Could you please help me?

What code do you have so far? It’s a lot easier to talk about this in the specifics of what you’re trying to do.

Ken,
I am nowhere.
It is pretty logical in my mind as I already built this app on excel (but it is not user friendly).
As my models stand:

  • Ingredient
  • Recipe, linked together by RecipeIngredient with a Foreign Key
  • Production, linked with Recipe by ProductionRecipe with a Foreign Key
    So for each Production I can have several Recipes and for each Recipes I can have several ingredients
    I need the list of the the of Ingredients for each production

What’s your experience with Django so far?

If you’ve worked your way through the Official Django Tutorial, you would have learned how to reference data through your foreign keys in step 2.

If you haven’t yet worked through that tutorial, I suggest you do so - there are a lot of fundamental concepts you’re going to want to become familiar with.

Ken,
I have a 6 month experience learning and coding at the same time, that’s all.
I don’t have a problem with foreign keys, I have a problem to retrieve and display the data form further levels.
I learned python first, then django, I am at ease with pandas for myself (but not for my customers). I am very bad with HTML and in design (that’s why I want to stay with the admin)

Ok, so what specifically are you trying to do that you don’t understand? Please answer this question in terms of the models you are using, and let’s address this one point at a time. What’s the first step that has you stalled?

Also, I’m going to ask again that you edit your original post to include the ``` “fences” around your original code files to make them readable.

Thanks Ken,

I will do my best so you will be able to help me

in the app “purchase” (everything is working fine, I normally don’t need help there):

models.py

from django.db import models


"""all the available units to purchase, store and use the ingredients"""
UNIT = [('kg', 'kg'), ('litre', 'litre'), ('pièce', 'pièce'), ('paquet', 'paquet'), ('colis', 'colis')]


class StoragePlace(models.Model):
    place_id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=60, verbose_name='nom')
    TEMPERATURE_CHOICES = [('T°<-18°C', 'T°<-18°C'),
                           ('0°C<T°<2°C', '0°C<T°<2°C'),
                           ('0°C<T°<4°C', '0°C<T°<4°C'),
                           ('15°C<T°<20°C', '15°C<T°<20°C')]
    temperature = models.CharField(max_length=60,choices=TEMPERATURE_CHOICES, verbose_name='température')
    temperature_control_needed = models.BooleanField(default=False, verbose_name='besoin de contrôler la température')

    class Meta:
        verbose_name = 'emplacement de stockage'
        verbose_name_plural = 'emplacements de stockage'

    def __str__(self):
        return '{}'.format(self.name)


class Supplier(models.Model):
    """to create suppliers"""
    supplier_id = models.AutoField(primary_key=True)
    company_name = models.CharField(max_length=60, verbose_name='raison sociale')
    adress = models.CharField(max_length=60, blank=True, verbose_name='adresse')
    adress_information = models.CharField(max_length=60, blank=True, verbose_name="complement d'adresse")
    zipcode = models.IntegerField(blank=True, null=True, verbose_name='code postal')
    city = models.CharField(max_length=60, blank=True, verbose_name='ville')
    phone_number = models.CharField(max_length=15, blank=True, verbose_name='telephone')
    email = models.EmailField(blank=True,)
    rcs = models.CharField(max_length=60, blank=True, verbose_name="n°RCS + tribunal")
    siret = models.CharField(max_length=60, blank=True, verbose_name="n°SIRET")
    VAT = models.CharField(max_length=60, blank=True, verbose_name="n°TVA")

    def __str__(self):
        return '{}'.format(self.company_name)

    class Meta:
        verbose_name = 'fournisseur'


class SupplierContact(models.Model):
    """to create different contacts for the supplier, eg: director, accountant..."""
    contact_id = models.AutoField(primary_key=True)
    supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE, verbose_name='fournisseur')
    name = models.CharField(max_length=60, verbose_name='nom')
    surname = models.CharField(max_length=60, verbose_name='prénom')
    job_description = models.CharField(max_length=60, blank=True, verbose_name='poste',
                                       help_text='ex: dirigeant, comptable')
    phone_number = models.CharField(max_length=15, blank=True, verbose_name='telephone')
    mobile_number = models.CharField(max_length=15, blank=True, verbose_name='portable')
    email = models.EmailField(blank=True)

    def __str__(self):
        return '{} {}'.format(self.name, self.surname)

    class Meta:
        verbose_name = 'contact fournisseur'


class IngredientCategory(models.Model):
    """to define categories of ingredients like food, packaging, vegetables, fruits..."""
    ingredient_category_id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=60, verbose_name='nom', help_text='ex: ingrédient, épice, emballage...')

    class Meta:
        verbose_name = "type d'ingredient"
        verbose_name_plural = "type d'ingredient"

    def __str__(self):
        return self.name


class Ingredient(models.Model):
    """to create ingredients whether they are food, packaging or any other category,
    then to define their real cost according to a yield"""
    ingredient_id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=60, unique=False, verbose_name='nom')
    category = models.ForeignKey(IngredientCategory, on_delete=models.CASCADE, verbose_name='catégorie')
    supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE, verbose_name='fournisseur')
    supplier_item_number = models.CharField(max_length=20, blank=True, verbose_name='n° article fournisseur')
    supplier_item_name = models.CharField(max_length=30, blank=True, verbose_name='nom article fournisseur')
    ean13 = models.DecimalField(max_digits=13, decimal_places=0, blank=True, null=True)
    purchase_unit = models.CharField(max_length=6, choices=UNIT, verbose_name="unité d'achat")
    use_unit = models.CharField(max_length=6, choices=UNIT, verbose_name="unité d'utilisation")
    stock_unit = models.CharField(max_length=6, choices=UNIT, verbose_name="unité de stockage")
    invoiced_price = models.DecimalField(max_digits=7, decimal_places=3, verbose_name='prix facturé')
    net_weight = models.DecimalField(max_digits=6, decimal_places=3, blank=True,
                                     verbose_name='poids net ou volume unitaire')
    number_of_packs_per_purchase_unit = models.DecimalField(max_digits=3, decimal_places=0,
                                                            verbose_name='nombre de paquets par colis',
                                                            default=1,
                                                            help_text='nombre de pièces par carton')
    number_of_number_pieces_per_pack = models.DecimalField(max_digits=3, decimal_places=0, default=1,
                                                           verbose_name='nombre de pièces par paquet',
                                                           help_text='nombre de pièce par paquet')
    ingredient_yield = models.DecimalField(max_digits=3, decimal_places=2, default=1, verbose_name='rendement',
                                           help_text='ex: pour 93% mettre 0.93')
    is_vegan = models.BooleanField(default=False, verbose_name='végan')
    is_veggie = models.BooleanField(default=False, verbose_name='végératien')
    storage_place = models.ForeignKey(StoragePlace, on_delete=models.PROTECT, blank=True, null=True,
                                      verbose_name='lieu de stockage')
    storage_number = models.CharField(max_length=10, null=True, blank=True, verbose_name='emplacement')

# nested fields
    price_per_kg_ou_l = models.DecimalField(max_digits=7, decimal_places=3, blank=True, null=True,
                                            verbose_name='prix au kg ou l')
    net_weight_after_yield = models.DecimalField(max_digits=6, decimal_places=3, blank=True, null=True,
                                                 verbose_name='poids ou volume après rendement')
    price_per_kg_ou_l_after_yield = models.DecimalField(max_digits=7, decimal_places=3, blank=True, null=True,
                                                        verbose_name='prix de revient au kg ou l')
    price_per_piece = models.DecimalField(max_digits=6, decimal_places=3, blank=True, null=True,
                                          verbose_name='prix par pièce')

    @property
    def _price_per_kg_ou_l(self):
        """to calculate the price per kg or litre of the ingredient"""
        if self.purchase_unit == 'litre' or self.purchase_unit == 'kg':
            return self.invoiced_price
        else:
            return self.invoiced_price / self.net_weight

    @property
    def _net_weight_after_yield(self):
        """to calculate the wheight after a yield """
        return round(self.net_weight * self.ingredient_yield, 3)

    @property
    def _price_per_kg_ou_l_after_yield(self):
        """to calculate the price per kg after a yield"""
        return round(self._price_per_kg_ou_l / self.ingredient_yield, 3)

    @property
    def _price_per_piece(self):
        """to calculate the price per piece"""
        if self.purchase_unit == 'colis':
            return self.invoiced_price / (self.number_of_packs_per_purchase_unit *
                                          self.number_of_number_pieces_per_pack)
        elif self.purchase_unit == 'pièce':
            return self.invoiced_price
        elif self.purchase_unit == 'paquet':
            return self.invoiced_price / self.number_of_number_pieces_per_pack
        else:
            return 0

    def save(self, *args, **kwargs):
        self.price_per_kg_or_l = self._price_per_kg_ou_l
        self.net_weight_after_yield = self._net_weight_after_yield
        self.price_per_kg_ou_l_after_yield = self._price_per_kg_ou_l_after_yield
        self.price_per_piece = self._price_per_piece
        super().save(*args, **kwargs)

    def __str__(self):
        return self.name

in the app produce (which is working fine too, but I need help here):

from django.db import models
from django.db.models import Sum

from purchase.models import Ingredient


class Production(models.Model):
    """used to create a production number in order to insure traçability"""
    production_id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=60, blank=True, null=True, verbose_name='nom')
    date = models.DateField(blank=True, null=True)

    def __str__(self):
        return 'lot n° {} {}'.format(self.production_id, self.name)


class RecipeCategory(models.Model):
    """defines categories for the recipes (eg for a restaurant: desert, main course..."""
    recipe_category_id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=60, verbose_name='nom', help_text='ex: entrée, dessert, plat...')

    class Meta:
        verbose_name = "type de recette"
        verbose_name_plural = "type de recette"

    def __str__(self):
        return self.name


class Recipe(models.Model):
    """gives a name and describes the recipe and calculate its cost"""

    recipe_id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=60, verbose_name='nom')
    recipe_category = models.ForeignKey(RecipeCategory, on_delete=models.CASCADE, verbose_name="type de recette")
    recipe_steps = models.TextField(max_length=2000, verbose_name='mode opératoire')
    recipe_yield = models.DecimalField(max_digits=3, decimal_places=2, verbose_name='rendement', default=1,
                                       help_text='ex: pour 93% mettre 0.93')
    number_of_serving = models.IntegerField(default=1, verbose_name="nombre de parts, tranches...")
    UNIT_CHOICES = [("kg", "kg"), ("litre", "litre"), ("piece", "pièce")]
    unit = models.CharField(max_length=6, choices=UNIT_CHOICES, default='kg', verbose_name='unité')
    shelf_life = models.PositiveSmallIntegerField(default=0, verbose_name='durée de vie', help_text='en jours')

    # nested in lines
    recipe_weight = models.DecimalField(max_digits=6, decimal_places=3, null=True, blank=True,
                                        verbose_name='poids ou volume')
    recipe_price = models.DecimalField(max_digits=6, decimal_places=3, null=True, blank=True,
                                       verbose_name='prix de revient')
    recipe_price_per_kg = models.DecimalField(max_digits=6, decimal_places=3, null=True, blank=True,
                                              verbose_name='prix de revient au kg ou l')

    @property
    def _recipe_weight(self):
        if self.recipeingredient_set.count() == 0:
            return 0
        else:
            dict_1 = self.recipeingredient_set.aggregate(recipe_weight=Sum('quantity'))
            return round(dict_1['recipe_weight'] * self.recipe_yield, 3)

    @property
    def _weight_per_serving(self):
        if self.recipeingredient_set.count() == 0:
            return 0
        else:
            return round(self._recipe_weight / self.number_of_serving, 3)

    @property
    def _recipe_price(self):
        if self.recipeingredient_set.count() == 0:
            return 0
        else:
            dict_1 = self.recipeingredient_set.aggregate(recipe_price=Sum('ingredient_price'))
            return round(dict_1['recipe_price'], 3)

    @property
    def _price_per_serving(self):
        if self.recipeingredient_set.count() == 0:
            return 0
        else:
            return round(self._recipe_price / self.number_of_serving, 3)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = 'recette'


class RecipeIngredient(models.Model):
    recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE, verbose_name='recette')
    ingredient = models.ForeignKey(Ingredient, on_delete=models.CASCADE)
    quantity = models.DecimalField(max_digits=6, decimal_places=3, verbose_name='quantité')
    unit = models.CharField(max_length=10, editable=False, null=True, blank=True, verbose_name='unité')

    # nested in lines
    ingredient_price = models.DecimalField(max_digits=6, decimal_places=3, blank=True, null=True,
                                           verbose_name="prix total de l'ingrédient")
    quantity_per_serving = models.DecimalField(max_digits=6, decimal_places=3, blank=True, null=True,
                                               verbose_name="quantité d'ingrédient par part servie")
    price_per_serving = models.DecimalField(max_digits=6, decimal_places=3, blank=True, null=True,
                                            verbose_name="prix de l'ingrédient par part servie")
    production = models.ForeignKey(Production, on_delete=models.CASCADE, blank=True, null=True, editable=False)

    @property
    def _ingredient_price(self):
        if self.ingredient.use_unit == 'kg':
            return round(self.ingredient.invoiced_price / (self.ingredient.net_weight * self.ingredient.ingredient_yield) * self.quantity, 3)
        elif self.ingredient.use_unit == 'litre':
            return round(self.ingredient.invoiced_price / (self.ingredient.net_weight * self.ingredient.ingredient_yield) * self.quantity, 3)
        elif self.ingredient.use_unit == 'colis':
            return round(self.ingredient.invoiced_price * self.quantity, 3)
        elif self.ingredient.use_unit == 'paquet':
            return round(self.ingredient.invoiced_price, 3)
        else:
            return round(self.ingredient.price_per_piece * self.quantity, 3)

    @property
    def _quantity_per_serving(self):
        return round(self.quantity / self.recipe.number_of_serving, 3)

    @property
    def _price_per_serving(self):
        return round(self._ingredient_price / self.recipe.number_of_serving, 3)

    def save(self, *args, **kwargs):
        self.unit = self.ingredient.use_unit
        self.ingredient_price = self._ingredient_price
        self.quantity_per_serving = self._quantity_per_serving
        self.price_per_serving = self._price_per_serving
        super().save(*args, **kwargs)

    class Meta:
        verbose_name = 'liste des ingrédients par recette'
        verbose_name_plural = 'liste des ingrédients par recette'

    def __str__(self):
        return '{}'.format(self.ingredient)


class ProductionRecipe(models.Model):
    production = models.ForeignKey(Production, on_delete=models.CASCADE)
    recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE, verbose_name='recette')
    quantity = models.DecimalField(max_digits=10, decimal_places=3)

    def __str__(self):
        return '{} {}'.format(self.production, self.recipe)

    class Meta:
        verbose_name = 'recettes par production'

in admin.py

from django.contrib import admin

from .models import Recipe, RecipeCategory, RecipeIngredient, Production, ProductionRecipe


class RecipeIngredientAdminInLine(admin.StackedInline):
    model = RecipeIngredient
    fields = [('recipe', 'ingredient', 'quantity', 'unit'),
              ('_ingredient_price', '_quantity_per_serving', '_price_per_serving')]
    readonly_fields = ['unit', '_ingredient_price', '_quantity_per_serving', '_price_per_serving']
    extra = 0


class RecipeAdmin(admin.ModelAdmin):
    inlines = [RecipeIngredientAdminInLine]
    save_on_top = True
    save_as = True
    fields = [('recipe_category', 'name'),'recipe_steps', ('recipe_yield', 'number_of_serving', 'unit', 'shelf_life')]
    ordering = ['name']
    search_fields = ['name']
    search_help_text = 'recherche par nom'
    list_display = ['name', 'recipe_category', 'recipe_yield', 'number_of_serving', 'unit',
                    '_recipe_weight', '_weight_per_serving', '_recipe_price', '_price_per_serving']


class ProductionRecipeAdminInLine(admin.StackedInline):
    model = ProductionRecipe
    extra = 0
    # readonly_fields = ['best_before']
    fields = [('recipe', 'quantity')]


class ProductionAdmin(admin.ModelAdmin):
    inlines = [ProductionRecipeAdminInLine]
    save_on_top = True
    save_as = True
    fields = [('name', 'date')]
    ordering = ['name']
    search_fields = ['name']
    search_help_text = 'recherche par nom'


class ProductionRecipeAdmin(admin.ModelAdmin):
    list_display = ["production", "recipe", "quantity"]


class RecipeIngredientAdmin(admin.ModelAdmin):
    list_display = ['ingredient', 'recipe', 'production']


admin.site.register(Recipe, RecipeAdmin)
admin.site.register(RecipeCategory)
admin.site.register(Production, ProductionAdmin)
admin.site.register(ProductionRecipe, ProductionRecipeAdmin)
admin.site.register(RecipeIngredient, RecipeIngredientAdmin)

I need an admin view that will list:

  • all the ingredients
  • there production (so an ingredient that is used in 10 different productions will have 10 lines)
  • I will have to calculate the sum of the quantities of all the ingredients I need in order to make my productions (usually I am ok with the aggregation, the filters…)
    I will need to display the supplier so I can filter and prepare the order form(I do not need help there)
    I will modify the admin.py so I can export the lines I want as csv or excel (I do not need help there)

as I do not want to modify the ingredients I think that I will have to begin wtih something like this:

models.py

class IngredientProxy(Ingredient):
    production = models.ForeignKey("somecode I do not know what to do", on_delete=models.CASCADE)


    class Meta:
        proxy = True

and now I am stucked

Thanks for your help

It’s really going to be a whole lot easier if you just create a view (or a pair of views) to display this data.

Yes, you can probably create a ModelAdmin page with inlines and calculated fields, but my hunch is that it’s going to be a lot more work than just creating a ListView for your recipes linked to a DetailView for an individual recipe.

Ken,

thanks a lot but I am stucked anyway, I still do not know at all how to do that. I believe I need some loop somewhere but I am at odds about how to to that.

I totally manage loops to display datas from m2m but in the foreign key way (and such levels above) I don’t understand how it works. I read several time the documentation and didn’t get an hint about how to do that.

Could you please point me in the right direction?

Thanks in advance

If you haven’t worked your way through the Official Django Tutorial, now’s the time to do so. It’s going to teach you a lot of fundamental concepts that you’re going to need going forward.

Yes, the tutorial even includes a section where a loop is used to iterate over a queryset.

Ken,

I will have to go again through the tutorial. Thanks for your time

Dear Ken,

here is what I wanted to do. It is working perfectly:

class IngredientProxy(Ingredient):

    @property
    def quantity_consumed_in_production_since_last_inventory(self):
        """return the quantity of ingredients consumed in production since the last inventory --- in 'use_unit'"""
        total_quantity = 0
        last_inventory_date = self.get_last_inventory_date
        production_recipe_qs = ProductionRecipe.objects.filter(
            Q(recipe__recipeingredient__ingredient=self) &
            Q(production__date__gte=last_inventory_date)
        )
        for production_recipe in production_recipe_qs:
            recipe_ingredient = RecipeIngredient.objects.filter(
                recipe=production_recipe.recipe, ingredient=self
            ).first()
            if recipe_ingredient is not None:
                quantity = recipe_ingredient.quantity * production_recipe.quantity
                total_quantity += quantity
            else:
                pass
        return round(total_quantity, 3)

    class Meta:
        verbose_name = 'stock'
        verbose_name_plural = 'd - stock'
        proxy = True

I added a filter in order to get only the quantity used since the last inventory

Thanks for your time