Django类视图多表单验证求助:无法在form_invalid传递user_form
我明白你卡在哪了——Django的CreateView默认只认你设置的form_class,所以当第二个表单(UserCreationForm)验证失败时,form_invalid里根本拿不到它的实例,更别说显示错误信息了。别担心,咱们直接重写几个方法就能搞定,代码调整如下:
第一步:修正get_context_data,正确实例化两个表单
原来的代码只是把表单类传到context里,这样用户提交后没法保留输入值和错误信息。改成根据请求方法来实例化:
def get_context_data(self, **kwargs): context = super(TrainerCreateView, self).get_context_data(**kwargs) # 根据请求方法实例化user_form if self.request.method == 'POST': context['user_form'] = self.second_form_class(self.request.POST) else: context['user_form'] = self.second_form_class() return context
第二步:重写form_valid,同时验证两个表单
这里要先验证第二个表单,只有两个表单都有效时才保存数据。注意要根据你的模型关联关系调整(比如Trainer和User的外键关联):
def form_valid(self, form): # 先获取并验证user_form user_form = self.second_form_class(self.request.POST) if user_form.is_valid(): # 先保存User实例 user = user_form.save() # 关联Trainer和User,这里假设你的Trainer模型有user字段 trainer_instance = form.save(commit=False) trainer_instance.user = user trainer_instance.save() # 调用父类的form_valid完成跳转 return super().form_valid(form) else: # 如果user_form无效,手动调用form_invalid并传入user_form return self.form_invalid(form, user_form=user_form)
第三步:重写form_invalid,把user_form传到模板
默认的form_invalid只处理主表单,咱们扩展它,把验证失败的user_form也放到context里:
def form_invalid(self, form, user_form=None): # 如果没有传入user_form(比如主表单本身就验证失败的情况),就从POST数据重新实例化 if not user_form: user_form = self.second_form_class(self.request.POST) # 把两个表单都放到context里,传给模板 context = self.get_context_data(form=form, user_form=user_form) return self.render_to_response(context)
模板里的小提示
最后在模板里,你需要分别渲染两个表单的字段和错误信息,比如:
<form method="post"> {% csrf_token %} <!-- 渲染TrainerForm --> {{ form.as_p }} <!-- 渲染UserCreationForm --> {{ user_form.as_p }} <button type="submit">创建训练师</button> </form>
这样不管是哪个表单验证失败,都会把错误信息显示出来,而且用户之前输入的内容也不会丢失。
内容的提问来源于stack exchange,提问作者Николай
相关产品推荐
相关产品推荐

