【问题标题】:Django - Add the same set of objects to a queryset using a ManyToMany fieldDjango - 使用 ManyToMany 字段将相同的对象集添加到查询集中
【发布时间】:2020-11-10 01:30:15
【问题描述】:

我有比萨饼和配料。

class Pizza(ModelBase):
    name = models.CharField(max_length=255)
    toppings = models.ManyToManyField('Topping', blank=True, related_name='pizzas')


class Topping(ModelBase):
    name = models.CharField(max_length=255)

假设我想将浇头TomatoCheese 添加到我数据库中的每个披萨中。 目前我可以用一个讨厌的 for 循环来做到这一点:

toppings = Toppings.objects.filter(Q(name='Tomato') | Q(name='Cheese'))
for pizza in Pizza.objects.all():
    pizza.toppings.add(*toppings)

有没有一种方法可以在不必循环所有比萨饼的情况下实现相同的目标?也许使用 Django 创建的直通表?

我知道我可以使用以下查询从所有比萨饼中删除浇头:

Pizza.toppings.through.objects.filter(topping__in=toppings).delete()

但我无法在没有 for 循环的情况下向多个比萨饼添加配料。

【问题讨论】:

  • afaik,没有循环你不能这样做。因为 Django 需要 add(...)set(...) 等方法来附加 M2M 对象,该方法仅适用于对象,不适用于查询集。

标签: django django-models django-orm


【解决方案1】:

您可以使用反向关系中的 .set() 来设置评论中已经提到的所有披萨的顶部,或者您可以通过表格条目执行 bulk_create

下面一行的内容:

topping_ids = Toppings.objects.filter(
     Q(name='Tomato') | Q(name='Cheese')
).values_list('id', flat=True)

pizza_ids= Pizza.objects.values_list('id', flat=True)

through_objects = [Pizza.toppings.through(topping_id=entry[0],
                   pizza_id=entry[1]) for entry in
                   itertools.product(topping_ids, pizza_ids)]


Pizza.toppings.through.objects.bulk_create(through_objects)

【讨论】:

    猜你喜欢
    • 2018-03-10
    • 1970-01-01
    • 2012-01-01
    • 2012-04-19
    • 2013-12-07
    • 2019-07-02
    • 1970-01-01
    • 2020-06-16
    • 1970-01-01
    相关资源
    最近更新 更多