这里的处理方法可能不是很科学,如果有人看到了这篇文章,错误之处请指出!
【1】首先建立一个简单的comment表单,并且views.py里要引入这个表单类
class CommentForm(forms.ModelForm): class Meta: model = Comment fields = ['content'] labels = {'content': ''}
这里使用了labels,显式指定不要显示标签。
【2】在对应的views函数里,新增显示这个表单,完成提交(关注else部分即可)
def one_note(request, pk): pk_note = get_object_or_404(MyNote, id=pk) if request.method != 'POST': date_and_tag() comment_form = CommentForm() # pk_note = MyNote.objects.get(id=pk) # 可以不用在这里用_ser.all()的方式预先得到all_comment,减少上下文传入的内容 # 而是直接到模板里通过for comment in pk_note.comment_set.all获得,注意模板里没有() all_comment = pk_note.comment_set.all().order_by('-add_time') context = {'pk_note': pk_note, 'date_index': list(set(date_list)), 'tag_index': list(set(tag_list)), 'all_comment': all_comment, 'comment_form': comment_form} return render(request, 'one_note.html', context) else: form = CommentForm(request.POST) if form.is_valid(): new_comment = form.save(commit=False) new_comment.relation_note = pk_note new_comment.save() return HttpResponseRedirect(reverse('notebook:one_note', args=[pk]))
【3】在模板里,显示要添加评论的地方,并且可以完成提交
{% block content %} <div class="left"> <div> <h3>{{pk_note.title}}</h3> <p>Create time:{{pk_note.pub_time}} Update time:{{pk_note.update_time}}</p> {% autoescape off %} <p>{{pk_note.content}}</p> {% endautoescape %} <p>{{pk_note.personal_tags.all}}</p> </div> <div id="comment"> <div> <form action="{% url 'notebook:one_note' pk_note.pk %}" method="post"> {% csrf_token %} {{comment_form.as_p}} <input type="submit" value="Add Comment" /> </form> </div> <div> {% for comment in all_comment %} <p>{{comment.add_time}}</p> <p>{{comment.content}}</p> {# <p>{{comment.relation_note}}</p> #} {% endfor %} </div> </div> </div> {% endblock %}
可以看到,这里已经增加了足够多的内容了:首先显示正文,然后显示添加评论,最后显示所有已经添加的评论。
由于添加评论的内容,是由函数one_note实现的,同时呈现正文和已添加的评论也是由它实现的,所以表单的action重新指向到one_note,并且将pk值传回。
在所有表单的操作中,如果判断method=‘POST’,则一个分支是进行存储,另一个分支就是负责呈现。
action操作时,指向views.py里的某个函数,并且告知为POST,则views根据判断,开始执行存储过程,存储完成后,进行重定向时,不会触发POST行为,所以自然会进入到呈现分支。
另一种情况下,从其他地方链接过来的,自然也没有POST行为,所以也是进入呈现分支。
【4】最后讲重点:一个新增的评论,如何完成绑定于某篇文章。
对比一下两次的form.save()相关的代码:
else: form = CommentForm(request.POST) if form.is_valid(): new_comment = form.save(commit=False) new_comment.relation_note = pk_note new_comment.save() return HttpResponseRedirect(reverse('notebook:one_note', args=[pk])) else: form = NoteForm(request.POST) if form.is_valid(): new_note = form.save() return HttpResponseRedirect(reverse('notebook:one_note', args=[new_note.pk]))
后者,我们添加一篇文章,从form接收数据后,这个note实例的所有定义的字段都齐全了,可以直接将他保存,之所以再赋值一下,是为了拿到pk值;
前者,因为所添加的评论还不知道绑定关系,所以要多走一步。
之前定义过但是一直没用到的relation_note属性,在这里需要操作一下。在django后台,很多事情会自动完成,所以我不知道relation_note用来干嘛,但是在前端,这个事情需要由代码人自己来完成。用form进行保存保存,使用commit=False,告知只是暂时,但不要存入数据库,同时赋值到一个变量,这个变量需要增加一个属性:relation_note,告知它绑定到谁:new_comment.relation_note = pk_note,然后再把new_comment存入到数据库。
这里为了获得pk_note,将他放到了if--else之外:pk_note = get_object_or_404(MyNote, id=pk)