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

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

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

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

Q&A

1回答

1789閲覧

Django - 複数のフォームを1つのページで用いる(UpdateView)

nk18

総合スコア14

Django

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

0グッド

0クリップ

投稿2019/05/06 14:55

編集2019/05/06 15:12

私は、ユーザーが自分の情報を登録および編集できるWebサイトを開発しています。 1ページに複数のフォームを使いたいと考えています。 CreateViewを使って登録フォームを作成できました。しかし、UpdateVIewを使用して情報を更新するページを作成する際に、フォームの初期値を追加する方法がわかりません。。

私のコード(view.py)は以下の通りです。初期値として formデータは追加できましたが、 form2は追加できておりません。初期値として form2データも追加する方法を教えてください。

class UserUpdate(OnlyYouMixin, generic.UpdateView): model = Profile form_class = ProfileForm second_form_class = ProfileNearStationForm template_name = 'accounts/user_form.html' def get_context_data(self, **kwargs): context = super(UserUpdate, self).get_context_data(**kwargs) if 'form' not in context: context['form'] = self.form_class(self.request.GET, instance=self.request.user) if 'form2' not in context: context['form2'] = self.second_form_class(self.request.GET, instance=self.request.user) return context def get(self, request, *args, **kwargs): super(UserUpdate, self).get(request, *args, **kwargs) form = self.form_class form2 = self.second_form_class return self.render_to_response(self.get_context_data()) def post(self, request, *args, **kwargs): self.object = self.get_object() form = self.form_class(request.POST, instance=self.request.user) form2 = self.second_form_class(request.POST, instance=self.request.user) if form.is_valid() and form2.is_valid(): profile = form.save(commit=False) profile.save() station = form2.save(commit=False) station.user = user station.save() messages.success(self.request, 'Settings saved successfully') return HttpResponseRedirect(self.get_success_url()) else: return self.render_to_response( self.get_context_data(form=form, form2=form2)) def get_success_url(self): return resolve_url('accounts:user_form', pk=self.kwargs['pk'])

▪️form.py

class ProfileForm(forms.ModelForm): name = forms.CharField(required=True) tel_number = forms.CharField(required=True) class Meta: model = Profile fields = ('name', 'tel_number') class ProfileNearStationForm(forms.ModelForm): prefecture = forms.ModelChoiceField(queryset=areas_model.Prefecture.objects.all(), required=True) railway = forms.ModelChoiceField(queryset=areas_model.Railway.objects.none(), required=True) station = forms.ModelChoiceField(queryset=areas_model.Station.objects.none(), required=True) memo = forms.CharField(required=False) class Meta: model = ProfileNearStation fields = ('prefecture', 'railway', 'station', 'memo')

▪️model.py

class Profile(models.Model): user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) name = models.CharField(max_length=255) tel_number = models.CharField(max_length=13) class ProfileNearStation(models.Model): prefecture = models.ForeignKey(areas_model.Prefecture, on_delete=models.CASCADE) railway = models.ForeignKey(areas_model.Railway, on_delete=models.CASCADE) station = models.ForeignKey(areas_model.Station, on_delete=models.CASCADE) memo = models.CharField(max_length=255, null=True) user = models.ForeignKey(User, on_delete=models.CASCADE)

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

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

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

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

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

guest

回答1

0

あくまでも class-based view を使う形で実現されたいですか?それとも目的のページが作れるのなら function-based view を使う形でも全然問題ないですか?

後者の場合は以下ご参考になると思いますので読んでみてください。

function-based view で書けば、わりとシンプルなコードで実現できるかと思います。以下、 function-based view で書いた場合の擬似コードです(細部は間違っているかもしれません、おおまかな流れのみ参考にしてください):

python

1def user_update(request, pk): 2 user = (pk に対応する user を取得する、無理なら 404 ) 3 profile = (user に対応する profile を取得する) 4 station = (user に対応する profile_near_station を取得する) 5 6 form1 = ProfileForm(request.POST or None, instance=profile) 7 form2 = ProfileNearStationForm(request.POST or None, instance=station) 8 9 if (form1 form2 ともに valid): 10 (form1 を使って profile を保存) 11 (form2 を使って station を保存) 12 (成功メッセージをセット) 13 return (リダイレクトレスポンス) 14 15 return (form1 と form2 を使ってフォームを描画)

作りによっては、 user が存在するのにそれに対応する profilestation が存在しない場合等も発生するかと思います。そのあたりは適宜処理するようにしてください。

投稿2019/05/07 04:43

gh640

総合スコア1407

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

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

nk18

2019/05/07 10:51

function-based viewで問題ございません。`pk に対応する user を取得する` や `user に対応する profile を取得する` 方法がまだわからないので、今一度調べてみます。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問