次に例を示します。
これらのクラスがあれば
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」という名前の著者が 1 人、および「Georfe」という名前の著者が 1 人います。最後の著者は間違いです。したがって、私が望むのは、「Georfe」を著者の 1 人として持つすべての書籍で、著者「George」に置き換えることです。
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))
しかし、この解決策は本当にエレガントで効率的だとは思いません。ループなしの解決策はありますか?
ベストアンサー1
注記:このコードは消去間違った「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()
2 つのモデルを結合する明示的なテーブル (「through」キーワード引数を使用) があれば、これはより簡単になると思います。その場合、関係テーブルに直接アクセスして、.update(id=george_author.id)
それに対して a を実行できます。