你不能从未保存的对象创建m2m关系。如果有pk,请尝试以下操作:
sample_object = Sample()sample_object.save()sample_object.users.add(1,2)
更新:阅读了saverio的答案后,我决定对这个问题进行更深入的研究。这是我的发现。
这是我最初的建议。它可以工作,但不是最佳选择。(注意:我使用
Bar的是
s和
a Foo而不是
Users和
a Sample,但你明白了。)
bar1 = Bar.objects.get(pk=1)bar2 = Bar.objects.get(pk=2)foo = Foo()foo.save()foo.bars.add(bar1)foo.bars.add(bar2)
它总共产生7个查询:
SELECt "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERe "app_bar"."id" = 1SELECt "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERe "app_bar"."id" = 2INSERT INTO "app_foo" ("name") VALUES ()SELECt "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERe ("app_foo_bars"."foo_id" = 1 AND "app_foo_bars"."bar_id" IN (1))INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 1)SELECt "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERe ("app_foo_bars"."foo_id" = 1 AND "app_foo_bars"."bar_id" IN (2))INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 2)我相信我们可以做得更好。你可以将多个对象传递给该
add()方法:
bar1 = Bar.objects.get(pk=1)bar2 = Bar.objects.get(pk=2)foo = Foo()foo.save()foo.bars.add(bar1, bar2)
如我们所见,传递多个对象可以节省一个SELECt:
SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERe "app_bar"."id" = 1SELECt "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERe "app_bar"."id" = 2INSERT INTO "app_foo" ("name") VALUES ()SELECt "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERe ("app_foo_bars"."foo_id" = 1 AND "app_foo_bars"."bar_id" IN (1, 2))INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 1)INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 2)我不知道你还可以分配对象列表:
bar1 = Bar.objects.get(pk=1)bar2 = Bar.objects.get(pk=2)foo = Foo()foo.save()foo.bars = [bar1, bar2]
不幸的是,这又增加了一个SELECt:
SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERe "app_bar"."id" = 1SELECt "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERe "app_bar"."id" = 2INSERT INTO "app_foo" ("name") VALUES ()SELECt "app_foo_bars"."id", "app_foo_bars"."foo_id", "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERe "app_foo_bars"."foo_id" = 1SELECt "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERe ("app_foo_bars"."foo_id" = 1 AND "app_foo_bars"."bar_id" IN (1, 2))INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 1)INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 2)让我们尝试分配一个pks 列表,如saverio建议的那样:
foo = Foo()foo.save()foo.bars = [1,2]
因为我们不获取两个
Bars,所以保存了两个SELECt语句,总共有5个:
INSERT INTO "app_foo" ("name") VALUES ()SELECT "app_foo_bars"."id", "app_foo_bars"."foo_id", "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERe "app_foo_bars"."foo_id" = 1SELECt "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERe ("app_foo_bars"."foo_id" = 1 AND "app_foo_bars"."bar_id" IN (1, 2))INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 1)INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 2)最终获胜者是:
foo = Foo()foo.save()foo.bars.add(1,2)
路过
pks到
add()让我们一共有4个查询:
INSERT INTO "app_foo" ("name") VALUES ()SELECt "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERe ("app_foo_bars"."foo_id" = 1 AND "app_foo_bars"."bar_id" IN (1, 2))INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 1)INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 2)


