Djangoで複数form をcreateViewで使う2(DB登録編)

完成コード(View)

#プレイヤーと同時に複数のセットを登録する試み
class CreatePlayerSetView(CreateView):
   form_class =PlayerForm
   form_class2 =CardForm


   template_name = 'p_card\CreatPlayerSet.html'


   def get_context_data(self, **kwargs):
       context= CreateView.get_context_data(self, **kwargs)
       form2 = self.form_class2(self.request.GET or None)
       context.update({'form2':form2})


       return context

   def form_valid(self, form):
       form2 = self.form_class2(self.request.POST or None)

       if form2.is_valid():
           with transaction.atomic():
               form.save()
               form2.save() 
       else:
           self.form_invalid(form)


       return HttpResponseRedirect(self.get_success_url())

   def get_success_url(self):
       return reverse_lazy('player:create_playerset')

ほかのものは前回のものとかわないのでそちらを参照

今回のポイント

def form_valid(self, form):

これはフォームの検証成功した後の処理を記述する

つまりformに数字しか入らないものに日本語が入っていたりしたときはこちらは実行されない(その時はform_invalid()が実行される)

しかしこの処理はform_classに指定したformに対して行われるものなのでform_class2に対しては一切検証されていない

そのためform_class2(self.request.POST or None)でPOST送信で送られてきた入力値をform_class2にいれて
if form2.is_valid():で入力値の検証をする

if form2.is_valid()を追加したものはform_class,form_class2の両方に対して入力値に不備がないと認められるので登録が行える

登録の前にwith transaction.atomic():を使う

これはトランザクション処理といってこの中にいる間にDBの処理が失敗した場合transaction.atomic()が宣言された直後の状態までDBをロールバックする
これにより片方だけ登録されることを防ぐことができる。

最後にdef get_success_url(self)
で登録終了後のジャンプ先を指定すれば完成

画像1

入力値が登録されていることを確認





この記事が気に入ったらサポートをしてみませんか?