0

我创建了一个表单来为我的博客项目将帖子保存到数据库中。我设计了索引页。现在我正在尝试创建一个表单来创建新帖子。在此之前我使用的是“manage.py shell”

这是我的看法:

def addpost(request):
    form = addForm()
    if request.method=="POST":
        titleform = request.POST['title']
        bodyform = request.POST['body']
        checkform = request.POST['isdraft']
        if form.is_valid():
                n = Post(title = titleform, body = bodyform, isdraft=checkform)
                n.save()

                return HttpResponseRedirect('/admin/')
    else:
        pass
    return render(request,'userside/add.html',{'form':form,})

我的模型.py:

class Post(models.Model):
    title = models.CharField(max_length = 100)
    body  = models.TextField()
    slug = AutoSlugField(populate_from='title',unique=True)
    posted = models.DateField(auto_now_add=True)
    isdraft = models.BooleanField()
    def __unicode__(self):
        return self.title

    @permalink
    def get_absolute_url(self):
        return ('view_blog_post',None, {'postslug':self.slug})

class addForm(forms.Form):
    title = forms.CharField(max_length=100)
    body  = forms.CharField(widget=forms.Textarea)
    isdraft = forms.BooleanField()

如果我将表单提交为“isdraft”字段为 False(未选中);它给出了如下错误:

/admin/addpost/ 处的 MultiValueDictKeyError

“未在”中找到密钥“isdraft”

如果我将表单提交为“isdraft”字段为 True(checked);它什么也没给。只是令人耳目一新的形式。没有将数据添加到数据库中。

我做错了..

谢谢你

编辑: Dmitry Beransky 的回答适用于复选框错误。但它仍然没有将任何数据添加到数据库中。只是刷新表单。

4

3 回答 3

0

如果您的 HTML 表单中未选中复选框,则它的名称/值将不会包含在浏览器发送到您的服务器的数据中。这意味着 request.POST 字典不会包含 'isdraft' 的条目,这反过来会在您尝试读取 isdraft 值时导致键错误。一种解决方案是将您从发布的数据中读取值的方式更改为:

    checkform = request.POST.get('isdraft', False)

如果在字典中找不到 isdraft,而不是抛出错误,这会将 checkform 设置为 False (在缺少键的情况下的默认值)

于 2012-08-19T18:45:04.827 回答
0

使用表单的全部意义在于它负责验证和清理,即将值转换为正确的数据类型。这就是为什么您应该访问form.cleaned_data而不是reques.POST,并且您应该在if form.is_valid()检查中进行。

编辑

我刚刚注意到您从未将 request.POST 传递给表单。所以form.is_valid()永远不会是真的。

请返回并阅读有关在视图中使用表单的文档。

于 2012-08-19T19:03:56.410 回答
0

也许您的表单根本无法验证。您是否检查过您的代码是否在 ifform.is_valid()语句之后到达了这些行?如果他们这样做了,那么您所做的就是正确的,应该为您的新条目创建 db 行,尽管您可以使用
Post.objects.create(....),这将消除调用方法的需要save()

不过有几点:

  • 而不是检查request.POST,检查request.method == 'POST',因为可能有一个帖子有一个空的 POST 字典(如果没有提交任何参数),在这种情况下request.POST无法提供正确的检查。
    有关更多信息,请参阅文档:request.POST

  • 而不是使用request.POST['var_name'],使用request.POST.get('var_name', 'default_value'),因为这样做request.POST['var_name']可能会导致一些异常(例如在未提供参数的情况下,例如您的 checkform 变量发生的情况)

  • 尝试通过 form.cleaned_data 访问这些变量

最后,你最后不需要 else 语句,只需使用缩进即可:)

于 2012-08-19T19:05:11.093 回答