【问题标题】:Django ModelForm initial doesn't work unless in <form>除非在 <form> 中,否则 Django ModelForm 初始值不起作用
【发布时间】:2011-08-09 18:47:06
【问题描述】:

也许我的方法不好,但假设这种通用场景:

我有包含 cmets 的博客。博客页面有一个用于创建 cmets 的表单。注释有一个 ModelForm,实际的 HTML 是有选择地完成的。外键当然是不可见或不呈现的。提交时,评论的外键需要与博客相关联。

如果我使用带有注释 ModelForm 的博客外键的初始值,它不会保留在 POST 中。有道理,因为它不在表单标签中。

我可以在表单调用的视图中的 POST 之后附加它,但 ModelForm(request.POST).data 是不可变的。我可以做 ModelForm(request.POST).save(commit=False) 但这意味着评论的模型的博客外键可以是空白的,从模型的角度来看这并没有什么意义。

这样做的正确方法是什么?似乎是一个非常标准的用法。

谢谢

【问题讨论】:

  • 一个想法:用正确的外键创建新的评论模型实例,用新的模型实例和帖子数据调用modelform构造函数,然后保存。这样可以避免保存两次感觉有点奇怪(纯个人意见)

标签: django django-models django-forms


【解决方案1】:

这是另一种方式:

def add_comment(request, blog_id):
    blog = get_object_or_404(Blog, blog_id)

    comment = Comment(blog=blog)

    if request.method=='POST':
        form = CommentForm(request.POST, instance=comment)
        if form.is_valid():
            form.save()
            return HttpResponse('success')
    else:
        form = CommentForm(instance=comment)

    context = { 'blog':blog,
                'form':form, }

    return render_to_response('add-comment.html', context,
        context_instance=RequestContext(request))

【讨论】:

  • 我如何确保 comment.blog 不会被黑客 POST 覆盖?
  • 被黑的 POST 是什么意思?
  • 好吧,意图是用户 POST 不包含类似 {'blog_id': 100} 的任何内容,因为表单标签不包含任何与 'blog_id' 相关的内容,但非典型用户几乎可以放置任何内容在 POST 中,可以放一个 id。如果评论实例有 blog_id 并且 POST 也有 blog_id,我可以防止覆盖吗?
  • 从您的 Meta 表单中排除博客字段。非典型用户可以将任何他想要的内容放入 POST,但只会查看表单中包含的字段。
【解决方案2】:

我假设您的视图知道它正在处理哪个 Blog 实例。

# get an unsaved comment instance
comment = form.save(commit=False)

# set the foreign key to blog
comment.blog = blog

# save it to the db
comment.save()

这是执行此操作的标准方式。是的,您的评论实例对 Blog 的外键在短时间内是 None ,但这并不重要,只要您不保存它(或在 FK 定义上设置 null=True )。 commit=False 表示它不会命中数据库,这就是为什么您必须稍后手动保存评论。

【讨论】:

    猜你喜欢
    • 2015-04-15
    • 2019-08-11
    • 1970-01-01
    • 2018-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-15
    • 2016-09-20
    相关资源
    最近更新 更多