Django根据添加表单编辑表单?
我做了一个不错的表单,还有一个复杂的“添加”功能来处理它。这个功能是这样开始的……
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
字段,这样add
功能就知道它在编辑什么。但是这样做有几个问题:
- 我该在哪里设置
article.id
呢?它必须在form.save
之后,因为这是创建文章的地方,但实际上它根本不会到达那里,因为表单因为唯一性限制而无效(除非用户编辑了所有内容)。我可以直接去掉is_valid
的检查,但那样form.save
就会失败。 - 如果表单实际上是无效的,我在编辑功能中动态添加的字段就不会被保留。
那我该怎么处理这个呢?
2 个回答
3
在表单中,你可以有一个隐藏的ID字段。在编辑表单的时候,这个ID会和表单一起提交。而在添加表单的时候,你可以在请求中设置这个ID,比如:
formData = req.POST.copy()
formData['id'] = getNewID()
然后把这些表单数据传递给表单。
116
如果你是从一个模型表单(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',)