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

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

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

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

Q&A

1回答

2590閲覧

djangoで複数のformをつけたいが送信内容が連動してしまう

keraker

総合スコア46

Django

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

0グッド

0クリップ

投稿2020/07/30 04:30

編集2020/07/31 03:20

前提・実現したいこと

djangoで複数のレコードにそれぞれformをつけ、変更できるようにしたいです。

発生している問題・エラーメッセージ

送信する内容が連動してしまいます。
たとえばチェックボックスにひとつでもチェックを入れるとすべて同じものが送信されてしまうようです。

該当のソースコード

以下は適宜略してあります 

view.py class UploadView(TemplateView): def post(self, request, page=1): Friend_Form = self.Friend_Form_class(request.POST) Send_Form = self.Send_Form_class(request.POST) context = self.get_context_data(Friend_Form=Friend_Form, Send_Form=Send_Form) if Send_Form.is_valid(): for o in self.data: messages.info(request, request.POST) messages.info(request, o) Send_Form = self.Send_Form_class(request.POST, instance=o) Send_Form.save() context = { 'FriendForm': FriendForm, 'Send_Form': SendForm, 'data': self.paginator.get_page(page),} return render(self.request, 'sendmail/index.html', context)
index.html <form action="{% url 'sendmail:index' %}" method="POST"> <table class="table"> <tr> <th class="py-1">form</th> <th class="py-1">gender</th> <th class="py-1">name</th> <th class="py-1">mail</th> </tr> <!-- ここでレコードのかずだけformをつくりたい--> {% for item in data %} <tr> <td class="py-2">{{ Send_Form.as_p }}{% csrf_token %}</td> <td class="py-2">{{item.gender}}</td> <td class="py-2">{{item.name}}</td> <td class="py-2">{{item.mail}}</td> <tr> {% endfor %} </table> <button type="submit" >送信</button> </form>

試したこと

messages.infoで表示された内容は以下です。

チェックボックスをすべてチェックしない場合
<QueryDict: {'csrfmiddlewaretoken': ['V7yAWeVrQfxQWtfmHvBBEIDJEMEjiE4A26xcgozExh6KTWYZ6F07Mt19yCWLqZHb', 'V7yAWeVrQfxQWtfmHvBBEIDJEMEjiE4A26xcgozExh6KTWYZ6F07Mt19yCWLqZHb']}>
<Friend:id=1, taro(2)>
<QueryDict: {'csrfmiddlewaretoken': ['V7yAWeVrQfxQWtfmHvBBEIDJEMEjiE4A26xcgozExh6KTWYZ6F07Mt19yCWLqZHb', 'V7yAWeVrQfxQWtfmHvBBEIDJEMEjiE4A26xcgozExh6KTWYZ6F07Mt19yCWLqZHb']}>
<Friend:id=3, jiro(0)>

ひとつでもチェックした場合
<QueryDict: {'gender': ['on'], 'csrfmiddlewaretoken': ['yRUeAldlNxjTgBIauF8bzlrQjNk87WQfFQTQUvRyuzSNd4rNTPxHH6PgdDCAfhtQ', 'yRUeAldlNxjTgBIauF8bzlrQjNk87WQfFQTQUvRyuzSNd4rNTPxHH6PgdDCAfhtQ']}>
<Friend:id=1, taro(2)>
<QueryDict: {'gender': ['on'], 'csrfmiddlewaretoken': ['yRUeAldlNxjTgBIauF8bzlrQjNk87WQfFQTQUvRyuzSNd4rNTPxHH6PgdDCAfhtQ', 'yRUeAldlNxjTgBIauF8bzlrQjNk87WQfFQTQUvRyuzSNd4rNTPxHH6PgdDCAfhtQ']}>
<Friend:id=3, jiro(0)>

よろしくお願いします。

追記

使っているのはBooleanFieldなのですが、どうやらチェックボックスはチェックされていないときはなにも送信しないようです。また同じname属性をもつformは一番最後の値が適用されるために連動してしまっているようでした。

class SendForm(forms.ModelForm): class Meta: model = Friend fields = ['gender',]

強引ですが、hiddenのformではさむことで値を特定したあと、以下の関数でQueryDictをつくり直接渡してみました。もっとスマートなやり方を教えていただければ幸いです。

index.html <input type="hidden" name="gender" value="/"/> {{ Send_Form.as_p }}{% csrf_token %} <input type="hidden" name="gender" value="/"/>
view.py boxlist=self.checkbox_list(request.POST.getlist('gender')) for i,o in enumerate(self.data): Send_Form = self.Send_Form_class(boxlist[i], instance=o) Send_Form.save() def checkbox_list(self, list): boxlist=[] flag=True next=False on=QueryDict( "gender=on") off=QueryDict() #"/"ではさまれていればon "/"が二回続けばoff for box in list: if next: next=False elif box=="/" and flag: flag=False elif box=="/" and not flag: boxlist.append(off) flag=True else: boxlist.append(on) flag=True next=True return boxlist

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

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

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

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

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

ForestSeo

2020/07/31 00:24

for文の中にformを入れればいいんじゃないですか?
keraker

2020/07/31 03:22

同じname属性をもつformは一番最後の値が適用されるらしいのでうまくいきませんでした。
guest

回答1

0

Python

1<table class="table"> 2 <tr> 3 <th class="py-1">form</th> 4 <th class="py-1">gender</th> 5 <th class="py-1">name</th> 6 <th class="py-1">mail</th> 7 </tr> 8 {% for item in data %} 9 <form action="{% url 'sendmail:index' %}" method="POST" name="{{forloop.counter}}"> 10 <tr> 11 <td class="py-2">{{ Send_Form.as_p }}{% csrf_token %}</td> 12 <td class="py-2">{{item.gender}}</td> 13 <td class="py-2">{{item.name}}</td> 14 <td class="py-2">{{item.mail}}</td> 15 <td><button type="submit">送信</button></td> 16 <tr> 17 </form> 18 {% endfor %} 19</table>

同じname属性をもつformは一番最後の値が適用されるらしいのでうまくいきませんでした。

name="{{forloop.counter}}"にして、formを1回目のnameは1、2回目のnameは2 とする。

投稿2020/07/31 03:35

編集2020/07/31 04:39
ForestSeo

総合スコア2722

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

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

keraker

2020/07/31 04:20

試してみましたが、帰ってくるのが <QueryDict: {'gender': ['on'], 'csrfmiddlewaretoken': ['V7srfw6rOIEdaAn3AYLGxtpch3HZcRM926r3zGKEvKd7736GZ8acFeNCbTZrkcpK']}> なのでindexでの変更は影響されないようです。
keraker

2020/07/31 14:05

index.htmlでの変更でした
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問