我已经研究了这个以及那里的许多答案(形式集,前缀等),但没有一个正是我之后...
我有一个应用程序,允许用户将卡张贴到棋盘上,每张卡可以有零个或多个评论。我已经设置了数据库关系,所以如果我手动添加板,卡或注释对象,我可以在模板中显示它们。
卡片表格也有效,所以这不是问题。但是现在我想用textarea
事件(我使用jQuery)显示评论click
。问题是,表单没有显示字段。这是表单代码:
class AddCommentForm(ModelForm):
class Meta:
model = Comment
fields = ['message']
message = forms.CharField(
widget=forms.Textarea(
attrs={
'class': 'form-control comment-input'
'name': 'message',
'placeholder': 'Comment away...'
}
),
required=False,
)
正确地说,当Django呈现表单时,它会使用id
。在这种情况下,它最终为id_message
或message
(取决于我是否在表单类中指定)。当然,在HTML中,这并不好。我在shell中证实了这一点:
>>> import django; import project
>>> from apps.board.forms import AddCommentForm
>>> comment_form = AddCommentForm(); print(comment_form)
<tr><th><label for="message">Message:</label></th><td><textarea class="form-control comment-input" cols="40" id="message" name="message" placeholder="Comment away..." rows="10">
</textarea></td></tr>
所以我想到了使用formsets
,但它似乎不太正确,因为据我所知,它们适用于一个form
标记内的多种形式。我的情况不同,因为每张卡都有零个或多个注释,HTML的流程表明应该有几个form
个元素。
另一个挑战是我需要有两个视图:一个用于处理卡片,另一个用于处理每个注释。我目前正在使用不同的操作值来完成此操作,它似乎可以正常工作。
似乎我的用例并不那么奇怪,我可以想到会出现这种情况的几种情况:Twitter回复,博客帖子的评论等等。我只是不能让Django工作有这个。
我还应该注意,我可以手动完成这项工作:
<label>
<textarea class="form-control comment-input" name="message"></textarea>
<button type="submit"></button>
</label>
更新
以下是视图片段:
class AddCommentView(View):
model = Comment
form_class = AddCommentForm
template_name = 'somedir/template.html'
@method_decorator(login_required)
def get(self, request):
comment_form = self.form_class()
return render(request, self.template_name, {
'comment_form': comment_form
})
如果表单正常(从上面的代码段和shell测试中),我希望这会在页面上显示。
URLConf在这里:
url(r'^comment/add/$', AddCommentView.as_view(), name='add_comment_view'),
在写这篇文章时,我看到一个令人困惑的作品。该视图的网址为/comment/add/
,但我希望该表单在/dashboard/
呈现。问题是该URL已有另一个视图。
如果我构建没有Django表单的表单,则将数据发布到/comment/add/
,注释将被创建并保存在数据库中。所以我想我还在尝试弄清楚如何在一个模板中使用多个表单的两个视图。 @Daniel Roseman指出使用prefix
,我想这值得探讨更多。
更新2
所以我通过删除该视图的URL并将视图合并到一个视图中来使用前缀。两种形式,一种视图,一种模板。但...
来源仍显示重复id
。我最终没有将id
放在表单属性列表中。由于这是无效的HTML,最好的解决方法是什么?
在我看来:
card_model = Card
comment_model = Comment
card_form_class = AddCardForm
comment_form_class = AddCommentForm
. . .
@method_decorator(login_required)
def get(self, request):
card_form = self.card_form_class(prefix='card')
comment_form = self.comment_form_class(prefix='comment')
. . .
更新3
我找到了解决这个问题的方法。要实例化表单,您需要添加auto_id=False
以防止复制id
:
comment_form = self.comment_form_class(prefix='comment', auto_id=False)
答案 0 :(得分:2)
在实例化表单时,可以使用prefix
参数为其提供非冲突的ID。
答案 1 :(得分:0)
虽然使用Django表单prefix
部分正确(感谢@ Daniel Roseman),但我认为有多少表单元素无关紧要的说法并不完全正确。它确实很重要,因为默认情况下,前缀意味着以一种形式使用(因为它创建了多个复制id
)。要以多种形式使用它,您还需要auto_id=False
。这可以防止Django表单生成id。