我试图在一个基于类的视图中保存两个表单。表单是经典的用户表单和个人资料表单,其中Profile
的用户属性指向模型中带有user = models.OneToOneField()
的用户。
views.py
:
class ProfileEdit(LoginRequiredMixin, FormView):
template_name = 'profiles/profile_form.html'
success_url = reverse_lazy('profile_edit')
def get_context_data(self, **kwargs):
context = super(ProfileEdit, self).get_context_data(**kwargs)
user = self.request.user
profile = Profile.objects.get(user=user)
user_form = UserForm(instance=user)
profile_form = ProfileForm(instance=profile)
context['forms'] = [user_form, profile_form]
return context
def post(self, request, *args, **kwargs):
user = self.request.user
profile = Profile.objects.get(user=user)
user_form = UserForm(request.POST, instance=user)
profile_form = ProfileForm(request.POST, instance=profile)
if user_form.is_valid() and profile_form.is_valid():
user_form.save()
profile_form.save()
messages.success(self.request, "Your profile was updated.")
return redirect(reverse('profile_edit'))
else:
return super(ProfileEdit, self).get(request, *args, **kwargs)
在基本的获取请求中,我得到了
'NoneType' object is not callable
那是因为我没有提供form_class
,但我不想声明form_class
,因为我有两种形式。我在post
方法中声明了这些表单。我应该继承FormView
还是有更好的东西使用?
此外,get_context_data
是否是实例化表单的正确位置?
答案 0 :(得分:2)
您可以将两种形式合二为一:
class UserForm(forms.ModelForm):
class Meta:
model = User
class UserProfileForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
# magic
self.user = kwargs['instance'].user
user_kwargs = kwargs.copy()
user_kwargs['instance'] = self.user
self.user_form = UserForm(*args, **user_kwargs)
# magic end
super(UserProfileForm, self).__init__(*args, **kwargs)
self.fields.update(self.user_form.fields)
self.initial.update(self.user_form.initial)
def save(self, *args, **kwargs):
self.user_form.save(*args, **kwargs)
return super(ProfileForm, self).save(*args, **kwargs)
class Meta:
model = UserProfile
答案 1 :(得分:0)
这里有一些选项,但我会使用简单的TemplateView或类似的
使用适当的参数
在get和post中实例化表单 def get(...):
self.user_form = UserForm(instance=user)
self.profile_form = ProfileForm(instance=profile)
return super().get(...)
def post(...)
self.user_form = UserForm(request.POST, instance=user)
self.profile_form = ProfileForm(request.POST, instance=profile)
if valid:
save_stuff()
return redirect()
return render_to_response(...) or super().get(...)
def get_context_data(self, **kwargs):
context = super(ProfileEdit, self).get_context_data(**kwargs)
context['forms'] = [self.user_form, self.profile_form]
return context
然后get_context_data将不处理get或post
的逻辑