如何处理大型表单中的错误?

时间:2014-10-01 07:36:35

标签: python django django-forms django-1.7

我刚刚开始使用formsets而且我在制作用户友好的错误系统时遇到了麻烦。

因此,用户会看到一个列表视图,向他显示已写入表单集的模型的所有实例。此页面旨在向他显示数据并对其进行编辑。

在我使用大量单独的表单和每个表单的保存按钮之前。但现在我想改进它以获得一个为所有表单提供单个保存按钮的formset。

但是出现了我的问题:之前我曾经通过“action”将用户发送到处理请求的另一个url(例如... / update /),然后将他发送回他之前看到的列表视图。这是为了避免在击中F5时多次提交。

但是现在如果我这样做并且只有一个表单错误,那么用户输入的所有信息都将丢失。

所以我停止使用额外的URL并使处理部分成为列表视图。现在我可以在每个表单上使用form.error,但是当用户按F5时也会重新提交。

有两种方法可以同时使用吗?

另外:我还有一张额外的表格。但是如果用户更改它,并且我将POST数据提供给formset,保存它然后将其放回页面我丢失了额外的formset,因为现在前者额外显示新输入的实例并且没有真正的额外字段将离开,直到刷新页面而不发送帖子数据。

这是我的观点:

class BVServerListView(View):
  def get(self, request):
    eigene_server = Server.objects.filter(user=request.user)
    EigeneServerFormset = modelformset_factory(Server, extra=1, form=ServerForm)
    eigene_server_formset = EigeneServerFormset(queryset=eigene_server)
    context = {'eigene_server': eigene_server_formset,}
    return render(request, 'bildverteiler/server_list.html', context)
  def post(self, request):
    eigene_server = Server.objects.filter(user=request.user)
    EigeneServerFormset = modelformset_factory(Server, extra=1, form=ServerForm)
    eigene_server_formset = EigeneServerFormset(request.POST, request.FILES)
    for form in eigene_server_formset.forms:
      if form.data.get('delete', False):
        server = Server.objects.get(user=request.user, name=form.data['name'])
        server.delete()
      else:
        if form.has_changed() and form.is_valid():
          server = form.save(commit=False)
          server.user = request.user
          server.save()
    context = {'eigene_server': eigene_server_formset,}
    return render(request, 'bildverteiler/server_list.html', context)

1 个答案:

答案 0 :(得分:0)

在此处使用单个表单或表单集之间没有区别。答案是一样的:发布到同一个视图,但在成功保存后重定向。

你在这里做错的另一件事是逐个验证和保存个别表格。不要这样做,因为你最终会遇到第一种形式有效并得到保存的情况,但后续的形式是无效的,因此需要重新显示formset。相反,验证formset整体:

if eigene_server_formset.is_valid():
    for form in eigene_server_formset.forms:
        if form.cleaned_data.get('delete'):
            ... delete ...
        else:
            form.save()
    return HttpResponseRedirect('somewhere_else')
return render...