给定两个模型,由一个没有直通表的ManyToMany连接:
class Ingredient(models.Model):
name = models.CharField(max_length=255)
class Recipe(models.Model):
name = models.CharField(max_length=255)
ingredients = models.ManyToManyField(Ingredient)
如何找到配方中使用的成分的实例总数?
例如,如果我有两种成分(苹果和糖(和两种食谱(苹果派和甜甜圈(,我怎么知道食谱有 3 种用途(两种是因为苹果派使用苹果和糖,一种是因为甜甜圈使用糖(?
我可以用以下内容来做到这一点:
count = 0
for recipe in Recipe.objects.all():
count += recipe.ingredients.count()
但这会产生太多查询。
有没有一种简单的方法可以通过注释/聚合来获取这个数字?
我们可以这样尝试(当然是为了避免很多DB
命中。使用数据库聚合(。
from django.db.models import Count
recipes = Recipe.objects.annotate(count_ingredients=Count('ingredients'))
for recipe in recipes:
print(recipe.pk, recipe.count_ingredients)
Recipe.ingredients.through.objects.filter(ingredient=YOUR_INGREDIENT_HERE).count()
Recipe.through
是保存many_to_many字段对象的"秘密"表,一个新的 Recipe_ingredients
(Django 的默认名称(对象被创建。如果您想使用使用给定成分的食谱数量,您可以使用您的成分过滤该表并获取其计数。
对于您的示例,将创建这些:(伪(
Recipe_ingredients(ingredient=sugar, recipe=apple_pie)
Recipe_ingredients(ingredient=sugar, recipe=doughnut)
Recipe_ingredients(ingredient=apple, recipe=apple_pie)
从这里您可以使用该表计算任何内容,如果您想知道所有成分的总用途,它就像
Recipe.ingredients.through.objects.count()
recipes = Recipe.objects.all()
for recipe in recipes:
print(recipe.ingredient_set.count())