![](/img/trans.png)
[英]How to edit/update a model via Django form with manytomany field?
[英]How to update manytomany field in Django?
这是一个例子:
如果我有这些课程
class Author(models.Model):
name = models.CharField(max_length=45)
class Book(models.Model):
name = models.CharField(max_length=45)
authors = models.ManyToManyField(Author)
在数据库中,我有一个名为“George”的作者和另一个名为“Georfe”的作者。 最后一个是错误的。 所以我想要的是每本书都有“Georfe”作为他的作者之一取代作者“乔治”。
在SQL中真的很容易做到。 如果“George”的id = 3且“Georfe”的id = 7且关系表名称为“author_book”:
UPDATE author_book SET id=3 WHERE id=7;
用Django ORM可以做到这一点吗?
我找到了一种方法:我通过错误的作者的所有相关书籍循环,并做:
book.authors.add(Author.objects.get(id=3))
book.authors.remove(Author.objects.get(id=7))
但我发现这种解决方案并不优雅高效。 有没有循环的解决方案?
注意:此代码将删除错误的“georfe”作者,以及更新书籍以指向正确的作者。 如果你不想这样做,那么使用.remove()
作为@jcdyer的回答提及。
你能做这样的事吗?
george_author = Author.objects.get(name="George")
for book in Book.objects.filter(authors__name="Georfe"):
book.authors.add(george_author.id)
book.authors.filter(name="Georfe").delete()
我怀疑如果你有一个明确的表连接两个模型(使用“through”关键字arg)会更容易 - 在这种情况下,你可以直接访问关系表,并且可以只做一个.update(id=george_author.id)
就可以了。
使用自动生成的直通表,您可以执行两步插入和删除操作,这对于提高可读性非常有用。
george = Author.objects.get(name='George')
georfe = Author.objects.get(name='Georfe')
book.authors.add(george)
book.authors.remove(georfe)
assert george in book.authors
如果你有一个明确定义的直通表(authors = models.ManyToManyField(作者,通过= BookAuthors),那么你可以在BookAuthor上明确地改变关系。一个鲜为人知的事实是这个模型已经存在,它是由django自动生成的。通常如果您希望存储额外的数据(例如特定作者在多作者书中写过的章节),您应该只创建一个显式的直通模型。
# This line is only needed without a custom through model.
BookAuthor = Book.authors.through
book_author = BookAuthor.objects.get(author=georfe, book=great_american_novel)
book_author.author = george
book_author.save()
assert george in book.authors
>>> b = Blog.objects.get(id=1)
>>> e = Entry.objects.get(id=234)
>>> b.entry_set.add(e) # Associates Entry e with Blog b.
>>> new_list = [obj1, obj2, obj3]
>>> e.related_set.set(new_list)
此方法接受clear
参数来控制如何执行操作。 如果为False
(默认值),则使用remove()
新集中缺少的元素,并仅添加新的元素。 如果clear=True
,则调用clear()
方法,并立即添加整个集合。
和参考: 如何在django中更新m2m字段
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.