Django基于添加表单编辑表单?

mpe*_*pen 44 python forms django logic

我已经制作了一个很好的表格,并且有一个很复杂的"添加"功能来处理它.它像这样开始......

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 ...
Run Code Online (Sandbox Code Playgroud)

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

  1. article.id在哪里设置add功能?它必须是form.save因为那是文章创建的地方,但它甚至永远不会达到,因为由于唯一约束,表单无效(除非用户编辑了所有内容).我可以删除is_valid支票,但后来form.save失败了.
  2. 如果形式实际上无效的,我在编辑功能动态添加字段不会被保留.

那么我该如何处理呢?

Dan*_*aab 100

如果要从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
    })
Run Code Online (Sandbox Code Playgroud)

在你的urls.py:

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

edit添加和编辑都使用相同的视图,但只有编辑URL模式将id传递给视图.为了使您的表单更好地工作,您需要省略author表单中的字段:

class ArticleForm(forms.ModelForm):
    class Meta:
        model = Article
        exclude = ('author',)
Run Code Online (Sandbox Code Playgroud)

  • 伟大而彻底的榜样!谢谢!我学到的不仅仅是这个问题的解决方案. (5认同)
  • 很棒的答案!我认为它缺少模板动作表单标签的示例.我怎么知道何时在模板中调用article_new或article_edit?需要检查form.instance.id? (3认同)
  • @stmyd从技术上讲,你可以做`action ="."`,因为你想要发布到你要从中重新发送表单的同一个URL. (3认同)
  • @DanielNaab我知道这已经很老了但是我已经非常接近它了...我该如何设置`action`属性?它会是'r'^ article/new/$'`或`r'^ article/edit /(?P <id>\d +)/ $'`?谢谢! (2认同)