我创建了一个表单,将帖子保存到我的博客项目的数据库中。我设计了索引页面。现在我正在尝试创建一个表单来创建新帖子。在此之前我使用'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,})
我的model.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(选中);它什么都没有。只是刷新形式。没有将数据添加到db。
我做错了......
谢谢
编辑:Dmitry Beransky的答案适用于复选框错误。但它仍然没有将任何数据添加到数据库中。只是刷新表格。
答案 0 :(得分:0)
如果未在HTML表单中选中复选框,则其名称/值不会包含在浏览器发送到服务器的数据中。这意味着request.POST字典不会包含'isdraft'的条目,这会在您尝试读取isdraft值时导致键错误。解决方案是将您从发布数据中读取值的方式更改为:
checkform = request.POST.get('isdraft', False)
如果在字典中找不到isdraft而不是抛出错误,这会将checkform设置为False(缺少键时的默认值)
答案 1 :(得分:0)
使用表单的重点在于它负责验证和清理,即将值转换为正确的数据类型。这就是为什么你应该访问form.cleaned_data
而不是reques.POST
,你应该在if form.is_valid()
检查中进行访问。
修改强>
我刚刚注意到你从未将request.POST传递给表单。因此form.is_valid()
永远不会成真。
请返回并阅读有关在视图中使用表单的文档。
答案 2 :(得分:0)
也许你的表单根本没有验证。您是否检查过您的代码是否在if form.is_valid()
语句后达到了这些行?如果他们这样做,你所做的就是正确的,应该为你的新条目创建db行,尽管你可以使用
Post.objects.create(....)
,这样就不需要调用方法save()
。
但有些观点:
而不是检查request.POST
,检查request.method == 'POST'
,因为可能有一个帖子有一个空的POST dict(如果没有提交参数),在这种情况下{ {1}}无法提供正确的检查
有关详细信息,请参阅文档:request.POST
而不是使用request.POST
,使用request.POST['var_name']
,因为这样做request.POST.get('var_name', 'default_value')
可能会导致一些例外(如果没有提供参数,例如发生的事情)为你的checkform变量)
尝试通过form.cleaned_data
最后,你最后不需要else语句,只需使用缩进:)