[解決済み] 多対多フィールドを持つDjangoモデルのオブジェクトを作成する方法は?
2022-04-25 11:08:18
質問
私のモデルです。
class Sample(models.Model):
users = models.ManyToManyField(User)
の両方を保存したい。
user1
と
user2
を、そのモデルの中に入れています。
user1 = User.objects.get(pk=1)
user2 = User.objects.get(pk=2)
sample_object = Sample(users=user1, users=user2)
sample_object.save()
間違っているのは分かっていますが、私がやりたいことは分かってもらえたと思います。あなたならどうする?
どのように解決するのですか?
未保存のオブジェクトからm2mリレーションを作成することはできません。もし
pk
の場合は、これを試してみてください。
sample_object = Sample()
sample_object.save()
sample_object.users.add(1,2)
更新しました。 を読んでから saverioさんの回答 この問題をもう少し詳しく調べてみることにしました。以下は私の調査結果です。
これは私が最初に提案したものです。動作はしますが、最適とは言えません。(注意: 私は
Bar
sと
Foo
の代わりに
User
を使用し
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)
見ての通り、複数のオブジェクトを渡すと、1つのオブジェクトを保存します。
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]
残念ながら、この場合、さらに1つの
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]
をフェッチしないので、2つの
Bar
の場合、2つ保存されます。
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)
関連
-
[解決済み】ilocが「IndexError: single positional indexer is out-of-bounds」を出す。
-
[解決済み】syntaxError: 'continue' がループ内で適切に使用されていない
-
[解決済み] バイトを文字列に変換する
-
[解決済み] pipでPythonの全パッケージをアップグレードする方法
-
[解決済み] Pythonでオブジェクトが属性を持つかどうかを知る方法
-
[解決済み] インスタンスのクラス名を取得する?
-
[解決済み] Pythonのsuper()は多重継承でどう動くのか?
-
[解決済み】ネストされたディレクトリを安全に作成するには?
-
[解決済み】Pandas DataFrameのカラムヘッダからリストを取得する。
-
[解決済み】2つの辞書を1つの式でマージする(辞書の和をとる)には?)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
opencvとpillowを用いた顔認証システム(デモあり)
-
Python 人工知能 人間学習 描画 機械学習モデル作成
-
PythonはWordの読み書きの変更操作を実装している
-
Python 可視化 big_screen ライブラリ サンプル 詳細
-
Pythonの@decoratorsについてまとめてみました。
-
[解決済み] [Solved] sklearn error ValueError: 入力に NaN、infinity または dtype('float64') に対して大きすぎる値が含まれている。
-
[解決済み】ImportError: sklearn.cross_validation という名前のモジュールがない。
-
[解決済み] _tkinter.TclError: 表示名がなく、$DISPLAY環境変数もない。
-
[解決済み】socket.error: [Errno 48] アドレスはすでに使用中です。
-
[解決済み】Python: SyntaxError: キーワードは式になり得ない