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

Posted

技术标签:

【中文标题】如何在 Django 中一次将多个对象添加到 ManyToMany 关系?【英文标题】:How to add multiple objects to ManyToMany relationship at once in Django ? 【发布时间】:2011-06-24 23:24:13 【问题描述】:

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

* TypeError: unhashable type: 'list'

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

【问题讨论】:

【参考方案1】:

使用:object.m2mfield.add(*items),如documentation 中所述:

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

add(obj1, obj2, obj3, ...)

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

add(*[obj1, obj2, obj3])

附录:

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

【讨论】:

如果您查看管理器,它只会对对象执行 for 循环并调用它们的保存。 shell 的一个简短实验表明@sdolan 实际上(当前)是不正确的。 IE。当我查看生成的 SQL 时,我只看到一个插入语句: INSERT INTO app_one_twos (one_id, two_id) VALUES (1, 1), (1, 2), (1, 3), (1, 4);这是在 Django 1.4 中。 @KlaasvanSchelven:我不记得通过生成的 sql 进行了测试,但根据我的评论,我很确定我只是看了一眼源代码。请记住,这是 2 年前的事了,所以我希望事情已经优化了一点。 @sdolan 不,他们没有改进它。我只是在测试它。 有什么方法可以按值(例如 id)做到这一点?有时您没有对象列表,而是对象值列表(即 id)?而不是循环遍历并将所有对象抓取到另一个列表中......【参考方案2】:

添加,如果你想从查询集中添加它们

例子

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

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

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

group.permissions.add(*permissions)

发件人:Insert queryset results into ManytoManyfield

【讨论】:

这执行两个查询而不是一个:( 请注意,您不需要将其转换为列表。直接添加(*permissions)即可。 谢谢兄弟。这真的对我有帮助。我试图通过subject = Subject.objects.filter(connect_class=class_list)。我做了student_data.subject.add(*subject),它奏效了。【参考方案3】:

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

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

set 是一个新的细节:

>>> new_list = [obj1, obj2, obj3]
>>> e.related_set.set(new_list)

【讨论】:

set 我想一直都在那里。只是它过去在旧 Django 中通过赋值 e.related_set = new_list 等效于 e.related_set.set(new_list)。他们刚刚意识到“显式胜于隐式”。 注意:为简洁起见,set 删除所有现有的关联模型。因此,如果您想添加新对象列表并希望保持现有对象不变,请使用 add(*newlist) 当您想将记录更新到新集合时,此解决方案非常棒,并且如果对象已经在集合“obj1”中,那么数据库中的记录不会重新创建。 在当前 Django 版本 (3.2.6) 中工作方式相同

以上是关于如何在 Django 中一次将多个对象添加到 ManyToMany 关系?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在 C# winforms 中一次将文本写入多个文本框?

如何使用 JQuery 一次将多个图像添加到 DOM?

一次将多个文档添加到 Firestore 时的 UI 堆栈

尝试在 mvc 3 中一次将两个模型传递到同一个视图时出现问题

如何使用java代码在单个数据库中一次连接多个模式

一次将多个操作添加到核心 - 数据关系