【问题标题】:Django edit form based on add form?Django基于添加表单编辑表单?
【发布时间】:2010-12-23 16:16:57
【问题描述】:

我制作了一个漂亮的表格,以及一个用于处理它的大而复杂的“添加”函数。开头是这样的……

def add(req):
    if req.method == 'POST':
        form = ArticleForm(req.POST)
        if form.is_valid():
            article = form.save(commit=False)
            article.author = req.user
            # more processing ...

现在我真的不想在edit() 方法中复制所有这些功能,所以我认为edit 可以使用完全相同的模板,也许只需在表单中添加一个id 字段,这样@ 987654325@ 函数知道它在编辑什么。但是这有几个问题

  1. add 函数中我应该在哪里设置article.id?它必须在form.save 之后,因为这是创建文章的地方,但它甚至永远不会到达那个位置,因为由于独特的约束,表单是无效的(除非用户编辑了所有内容)。我可以删除is_valid 检查,但随后form.save 会失败。
  2. 如果表单实际上无效,我在编辑功能中动态添加的字段不会被保留。

那么我该如何处理呢?

【问题讨论】:

    标签: python django forms logic


    【解决方案1】:

    您可以在表单中隐藏 ID 字段,对于编辑表单,它将与添加表单的表单一起传递,您可以在 req.POST 中设置它,例如

    formData =  req.POST.copy()
    formData['id'] = getNewID()
    

    并将该 formData 传递给表单

    【讨论】:

      【解决方案2】:

      如果您从 ModelForm 扩展您的表单,请使用 instance 关键字参数。在这里,我们传递现有的instance 或新的@,这取决于我们是在编辑还是添加现有文章。在这两种情况下,实例上都设置了author 字段,因此不需要commit=False。另请注意,我假设只有作者可以编辑他们自己的文章,因此是 HttpResponseForbidden 响应。

      from django.http import HttpResponseForbidden
      from django.shortcuts import get_object_or_404, redirect, render, reverse
      
      
      @login_required
      def edit(request, id=None, template_name='article_edit_template.html'):
          if id:
              article = get_object_or_404(Article, pk=id)
              if article.author != request.user:
                  return HttpResponseForbidden()
          else:
              article = Article(author=request.user)
      
          form = ArticleForm(request.POST or None, instance=article)
          if request.POST and form.is_valid():
              form.save()
      
              # Save was successful, so redirect to another page
              redirect_url = reverse(article_save_success)
              return redirect(redirect_url)
      
          return render(request, template_name, {
              'form': form
          })
      

      在你的urls.py:

      (r'^article/new/$', views.edit, {}, 'article_new'),
      (r'^article/edit/(?P<id>\d+)/$', views.edit, {}, 'article_edit'),
      

      相同的 edit 视图用于添加和编辑,但只有编辑 url 模式将 id 传递给视图。要使此功能与您的表单很好地配合使用,您需要从表单中省略 author 字段:

      class ArticleForm(forms.ModelForm):
          class Meta:
              model = Article
              exclude = ('author',)
      

      【讨论】:

      • 在这种情况下,我建议将 m2m 关系(等)保存/验证放在表单而不是视图中......要么覆盖保存方法,要么可能查看表单集。我想这取决于你正在使用的环境......
      • 伟大而彻底的例子!谢谢!我学到的不仅仅是这个问题的解决方案。
      • 很好的答案!我认为它缺少模板操作表单标记的示例。我怎么知道何时在模板中调用 article_new 或 article_edit?需要检查 form.instance.id 吗?
      • @DanielNaab 我知道这已经很老了,但我已经很接近让它工作了。我应该将表单 action 属性设置为什么?是r'^article/new/$' 还是r'^article/edit/(?P&lt;id&gt;\d+)/$'?谢谢!
      • @stmyd 从技术上讲,您可以直接使用action=".",因为您想发布到您要从其发送表单的同一个 URL。
      猜你喜欢
      • 2010-12-29
      • 2018-12-03
      • 1970-01-01
      • 1970-01-01
      • 2011-03-05
      • 2015-02-24
      • 1970-01-01
      • 2012-05-27
      • 1970-01-01
      相关资源
      最近更新 更多