前提・実現したいこと
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