我有以下Django模型:
class Ingredient(models.Model):
name = models.CharField(max_length=200)
cost_per_kg = models.DecimalField(max_digits=19, decimal_places=10
class Recipe(models.Model):
name = models.CharField(max_length=200)
qty_in_kg = models.DecimalField(max_digits=19, decimal_places=10)
#qty_in_kg quantity of preparation
class RecipeIngredients(models.Model):
ingredient = models.ForeignKey(Ingredient)
recipe = models.ForeignKey(Recipe)
qty_in_kg_of_ing = models.DecimalField(max_digits=19, decimal_places=10)
#qty_in_kg_of_ing: qty of ingredient in kg required to make the qty_in_kg of recipe
我想获得制作食谱的总费用。
如何获取包含总成本的额外列的食谱查询集。
答案 0 :(得分:2)
首先,您缺少RecipeIngredient
模型中的字段,因为目前Recipe
和Ingredient
之间没有任何联系,因此无法收集所有成分给定的Recipe
。以下是在recipe
中带有外键RecipeIngredient
的更新模型,可以解决此问题。
class Ingredient(models.Model):
name = models.CharField(max_length=200)
cost_per_kg = models.DecimalField(max_digits=19, decimal_places=10
class Recipe(models.Model):
name = models.CharField(max_length=200)
qty_in_kg = models.DecimalField(max_digits=19, decimal_places=10)
#qty_in_kg quantity of preparation
class RecipeIngredients(models.Model):
ingredient = models.ForeignKey(Ingredient)
recipe = models.ForeignKey(Recipe)
qty_in_kg_rec = models.DecimalField(max_digits=19, decimal_places=10)
#qty_in_kg_rec: required to make qty_in_kg
您需要运行的脚本如下:
cost = 0
# Loading recipe
recipe = Recipe.objects.get(name="recipe_name")
# Finding every connection between recipe and ingredients
connections = RecipeIngredients.objects.filter(recipe=recipe).all()
for rec_ing in connections:
# Calculating every ingredient cost
cost += rec_ing.ingrdient.cost_per_kg * rec_ing.qty_in_kg_rec
# Calculating cost of recipe
cost = cost * recipe.qty_in_kg
答案 1 :(得分:1)
我们可以对其进行如下注释:
from django.db.models import F, Sum
subs = Sum(F('recipeingredients__qty_in_kg_of_ing') *
F('recipeingredients__ingredient__cost_per_kg'))
qs = Recipe.objects.annotate(
cost=F('qty_in_kg') * subs
)
这将导致查询如下:
SELECT r.*, (r.qty_in_kg * SUM((ri.qty_in_kg_of_ing * i.cost_per_kg))) AS cost
FROM recipe AS r
LEFT OUTER JOIN recipeingredients AS ri ON r.id = ri.recipe_id
LEFT OUTER JOIN ingredient AS i ON ri.ingredient_id = i.id
GROUP BY r.id
如果食谱中没有成分,则.cost
将为None
,而不是零。因此,在进一步处理数据时需要考虑到这一点。