代码改变世界

123-在前端添加评论,显式地指定绑定关系

2020-08-25 11:07  lzhshn  阅读(176)  评论(0编辑  收藏  举报

这里的处理方法可能不是很科学,如果有人看到了这篇文章,错误之处请指出!

 

【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)