栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何为具有多对多字段的Django模型创建对象?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何为具有多对多字段的Django模型创建对象?

你不能从未保存的对象创建m2m关系。如果有pk,请尝试以下操作:

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" = 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)


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/404875.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号