【问题标题】:How to retrieve all many_to_many relations for each objects in a single query如何在单个查询中检索每个对象的所有 many_to_many 关系
【发布时间】:2021-07-07 21:03:33
【问题描述】:

我有四张桌子:

class Recipe(models.Model):
    item_recipe = models.OneToOneField(Item, on_delete=models.CASCADE, related_name='item_recipe')
    items = models.ManyToManyField(Item, through='RecipeItem')


class RecipeItem(models.Model):
    item = models.ForeignKey(Item, on_delete=models.CASCADE)
    recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE)
    quantity = models.IntegerField(default=1)

class Item(models.Model):
    def __str__(self):
        return self.name

    name = models.CharField(max_length=200, unique=True)
    effects = ArrayField(models.CharField(max_length=200), blank=True, default=list)
    pods = models.IntegerField(null=True)
    level = models.IntegerField(null=True)
    type = models.CharField(max_length=200, null=True, blank=True, default="Ressource")
    image = models.URLField()

class Prix(models.Model):

    def __str__(self):
        return self.item.name

    prix_x1 = models.IntegerField(null=True)
    prix_x10 = models.IntegerField(null=True)
    prix_x100 = models.IntegerField(null=True)

    saved_at = models.DateTimeField()
    item = models.ForeignKey(Item, on_delete=models.CASCADE)

一个recipe由1到8个Item组成,指定数量的就是RecipeItem表。

我想要一个查询,提供每个食谱的价格。
换句话说,一个查询获取每个菜谱的所有商品及其价格并求和。

我找不到没有 for 循环的方法。

编辑

这是我目前所拥有的,它不漂亮而且没有效果..

items = Recipe.objects.all().select_related('item').annotate(
        prix1_ressource=Subquery(
            Prix.objects.filter(
                item=OuterRef('items')
            ).values('prix_x1').exclude(prix_x1__isnull=True).order_by('-saved_at')[:1]
        ),
        prix1_item=Subquery(
            Prix.objects.filter(
                item=OuterRef('item_recipe')
            ).values('prix_x1').exclude(prix_x1__isnull=True).order_by('-saved_at')[:1]
        )
    ).exclude(prix1_item__isnull=True).values('id', 'item_recipe__name', 'prix1_ressource', 'items__name',
                                              'recipeitem__quantity', 'prix1_item',
                                              'item_recipe__type', 'item_recipe')

for id in np.unique(items.values_list('id', flat=True)):
    item = items.filter(id=id)
    try:
        prix_craft = sum([i['recipeitem__quantity'] * i['prix1_ressource'] for i in item])
        gain = item[0]['prix1_item'] - prix_craft

    except TypeError:
        continue

【问题讨论】:

    标签: python-3.x django django-models orm


    【解决方案1】:

    真的没有很好的 SQL 方式。在某些时候,您或 Django 将不得不遍历查询中的所有项目并对它们求和。也许您可以通过使用内部联接(如 here 所记录的那样)来提高效率,使用它来预加载项目。但解析项目的当前Prix 可能需要每次单独查询。

    【讨论】:

    • 我明白了.. 你知道如何让它尽可能有效吗?因为目前我的循环很长,比如 12s ..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-19
    • 2011-06-06
    相关资源
    最近更新 更多