質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

1回答

4734閲覧

Django ManytoManyFieldのformの保存の仕方がわからない

african

総合スコア17

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2021/06/30 12:33

Djangoでスケジュール管理アプリを構築しようとしているのですが、
manytomanyFieldをhtml上にformという形で表示してそこで入力された値をDBに保存したいのですが、
TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. Use goals.set() instead.
というエラーがでてしまいます。。。

models.py

class Goal(models.Model): created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) name = models.CharField(max_length=50) class Task(models.Model): created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) name = models.CharField(max_length=100) goals = models.ManyToManyField(Goal)

views.py

def addTask(request): form = TaskForm(request.POST or None) if request.method == 'POST': if form.is_valid(): task = Task() # task.save(commit=False) task.name = form.cleaned_data['name'] task.goals = form.cleaned_data['goals'] instance = Task.objects.create( name = task.name, goals = task.goals, )

で実行してみると
TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. Use goals.set() instead.

というエラーが出てしまいます。

いろいろ検索してみたのですが、MOdelForm関係の情報はあったのですが、forms.FormからのmanytomanyFieldの扱い方に関する情報が見つけられず、ここで質問させていただきます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

m2mのフィールドをもつオブジェクトのインスタンスを作成する際にm2mフィールドを
指定することはできません。
そのため,以下のようにgoalsフィールドは除いてcreateする必要があります。

Python

1 instance = Task.objects.create(name = task.name)

次に,m2mフィールドに特定のオブジェクトを登録する際は,その特定のオブジェクトを
取得してから登録する必要があります。

Python

1 goals = Goals.objects.all() 2 instance = Task.objects.create(name = task.name)

最後に,m2mフィールドにsetします。

Python

1 goals = Goals.objects.all() 2 instance = Task.objects.create(name = task.name) 3 instance.goals.set(goals)

goals = Goals.objects.all()で複数のGoalsオブジェクトが取得される可能性が
ある場合はaddを使います。

Python

1 goals = Goals.objects.all() 2 instance = Task.objects.create(name = task.name) 3 instance.goals.add(*goals)

こちらはm2mに関するDjangoの公式ドキュメントです。
(ページの最初にcreate時の注意書きがされています)

最後に一点だけ。。。もう少しエラーの詳細が欲しかったです。

TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. Use goals.set() instead.

というエラーが出てしまいます。

ではなく,今後はエラー時のサーバーログもしくはターミナルの出力をそのまま貼り付けて
ご質問してみてくださいませ。

投稿2021/06/30 14:08

編集2021/06/30 14:15
Jp_ryos

総合スコア6

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問