คุณไม่สามารถสร้างความสัมพันธ์ m2m จากวัตถุที่ไม่ได้บันทึก หากคุณมีpk
s ลองสิ่งนี้:
sample_object = Sample()
sample_object.save()
sample_object.users.add(1,2)
อัปเดต:หลังจากอ่านคำตอบของ saverioฉันตัดสินใจที่จะตรวจสอบปัญหาในเชิงลึกอีกเล็กน้อย นี่คือสิ่งที่ฉันค้นพบ
นี่คือข้อเสนอแนะดั้งเดิมของฉัน มันใช้งานได้ แต่ไม่ดีที่สุด (หมายเหตุ: ฉันใช้Bar
s และ a Foo
แทนUser
s และ 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" = 1
SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERE "app_bar"."id" = 2
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))
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" = 1
SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERE "app_bar"."id" = 2
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)
ฉันไม่ทราบว่าคุณสามารถกำหนดรายการวัตถุ:
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" = 1
SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERE "app_bar"."id" = 2
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" = 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 (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)
ลองกำหนดรายการpk
s ตามที่แนะนำ saverio:
foo = Foo()
foo.save()
foo.bars = [1,2]
เนื่องจากเราไม่ได้ดึงข้อมูลทั้งสองBar
มาเราจึงบันทึก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" = 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 (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)
การส่งข้อความpk
เพื่อ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)