如何在Django中一次向ManyToMany关系添加多个对象?

phi*_*o20 160 django list manytomanyfield

基于Django文档,我应该能够一次传递多个对象以添加到一个多人关系但我得到一个

* TypeError:不可用类型:'list'

当我尝试传递一个列表中的django查询集.传递Queryset或ValuesListQueryset似乎也失败了.有没有比使用for循环更好的方法?

Yuj*_*ita 282

使用:object.m2mfield.add(*items)文档中所述:

add() 接受任意数量的参数,而不是它们的列表.

add(obj1, obj2, obj3, ...)
Run Code Online (Sandbox Code Playgroud)

要将该列表扩展为参数,请使用 *

add(*[obj1, obj2, obj3])
Run Code Online (Sandbox Code Playgroud)

附录:

Django不会调用obj.save()每个项目,而是使用bulk_create().

  • 来自shell的简短实验表明@sdolan实际上(当前)是不正确的.即,当我查看生成的SQL时,我只看到一个插入语句:INSERT INTO app_one_twos(one_id,two_id)VALUES(1,1),(1,2),(1,3),(1,4); 这是在Django 1.4中. (3认同)
  • 有什么办法可以按值(例如id)做到这一点?有时您没有对象列表而是对象值列表(即id)?而不是循环并将所有对象抓取到另一个列表中...... (2认同)

Dr *_*tan 39

要添加,如果要从查询集添加它们

# Returns a queryset
permissions = Permission.objects.all()

# Turns it into a list
permissions = list(permissions)

# Add the results to the many to many field (notice the *)

group = MyGroup.objects.get(name='test')

group.permissions.add(*permissions)
Run Code Online (Sandbox Code Playgroud)

发件人:将查询集结果插入ManytoManyfield

  • 这将执行两个查询,而不是一个:( (2认同)
  • 请注意,您不需要将其变成列表。只需直接添加(*权限)即可。 (2认同)

aer*_*ero 29

Django 1.9增加了添加多对多关系的其他方法.

文档:https://docs.djangoproject.com/en/1.9/ref/models/relations/#django.db.models.fields.related.RelatedManager.set

set 是一个新的精确:

>>> new_list = [obj1, obj2, obj3]
>>> e.related_set.set(new_list)
Run Code Online (Sandbox Code Playgroud)

  • 注意:为了简洁起见,set 会删除所有现有的关联模型。因此,如果您想要添加新对象列表并希望保持现有对象完整,请使用 add(*newlist) (4认同)
  • 我想,“集合”总是在那儿。只是它在较老的Django中通过分配`e.related_set = new_list`起作用,就相当于`e.related_set.set(new_list)`。他们只是意识到“明确胜于隐含”。 (2认同)
  • 当您想要将记录更新到新集合时,并且如果对象已经在集合“obj1”中,则该解决方案非常有用,而不是数据库中的记录重新创建。 (2认同)
  • 在当前 Django 版本 (3.2.6) 中的工作方式相同 (2认同)
  • set 方法默认为“clear=True”,但您可以通过传递“clear=False”显式更改它 (2认同)