在一个Django CBV中保存用户表单和资料
我正在尝试在一个基于类的视图中保存两个表单。这两个表单分别是经典的用户表单和个人资料表单,其中个人资料的用户属性通过 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
是实例化表单的合适地方吗?
2 个回答
0
这里有几种选择,但我建议你使用一个简单的TemplateView或者类似的东西。
在获取数据和提交数据时,用合适的参数来创建表单。
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就不会处理获取或提交数据的逻辑了。
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