十八、Django2.1 搭建多用户的博客网站——文章评论功能

96
麦典威
2.9 2019.02.20 08:39* 字数 711

目录:Django 2.1 从零开始搭建博客网站系列

服务器环境搭建(选学)

小试牛刀——简单的博客网站

庖丁解牛——多用户的博客网站之用户模块

庖丁解牛——多用户的博客网站之文章模块

华丽转身——多用户的博客网站之扩展功能

项目源码下载:https://github.com/jt1024/lehehe

正文:

1、数据模型类和表单类

在 ./article/models.py 中增加 Comment

class Comment(models.Model):
    article = models.ForeignKey(ArticlePost, on_delete=models.CASCADE, related_name="comments")
    commentator = models.CharField(max_length=90)
    body = models.TextField()
    created = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ('-created',)

    def __str__(self):
        return "Comment by {0} on {1}".format(self.commentator.username, self.article)

在 ./article/forms.py 中增加 CommentForm

class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ("commentator", "body",)

2、视图函数

修改 ./article/list_views.py 中的 article_detail 方法

def article_detail(request, id, slug):
    article = get_object_or_404(ArticlePost, id=id, slug=slug)
    total_views = r.incr("article:{}:views".format(article.id))
    r.zincrby('article_ranking', 1, article.id)

    article_ranking = r.zrange("article_ranking", 0, -1, desc=True)[:10]
    article_ranking_ids = [int(id) for id in article_ranking]
    most_viewed = list(ArticlePost.objects.filter(id__in=article_ranking_ids))
    most_viewed.sort(key=lambda x: article_ranking_ids.index(x.id))

    if request.method == "POST":
        comment_form = CommentForm(data=request.POST)
        if comment_form.is_valid():
            new_comment = comment_form.save(commit=False)
            new_comment.article = article
            new_comment.save()
    else:
        comment_form = CommentForm()

    return render(request, "article/list/article_content.html", {"article": article, "total_views": total_views, "most_viewed": most_viewed, "comment_form": comment_form})

3、视图模板

修改 ./templates/article/list/article_content.html 在点赞代码之后增加如下代码

<div>
            <h3><span class="glyphicon glyphicon-bullhorn"></span>本文有{{ comments.count }}评论</h3>
            {% for comment in article.comments.all %}
            <div>
                <p><strong>{{ comment.commentator }}</strong>说:</p>
                <p style="margin-left:40px;">{{ comment.body }}</p>
            </div>
            {% empty %}
            <p>没有评论</p>
            {% endfor %}

            <h3><span class="glyphicon glyphicon-send"></span>看文章,发评论,不要沉默</h3>
            <form action="." method="post" class="form-horizontal" role="form">{% csrf_token %}
                <div class="form-group">
                    <label for="inputEmail3" class="col-sm-2 control-label">评论员</label>
                    <div class="col-sm-10">
                        {{ comment_form.commentator}}
                    </div>
                </div>
                <div class="form-group">
                    <label for="inputEmail3" class="col-sm-2 control-label">评论</label>
                    <div class="col-sm-10">
                        {{ comment_form.body }}
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-sm-offset-2 col-sm-10">
                        <p><input type="submit" name="" value=" 发 评 论 " class="btn btn-primary"></p>
                    </div>
                </div>
            </form>
        </div>

修改后的完整代码如下

{% extends "base.html" %}
{% load staticfiles %}
{% block title %}articles list{% endblock %}
{% block content %}

{% with total_likes=article.users_like.count users_like=article.users_like.all %}
<div class="container">
    <div class="col-md-9">
        <header>
            <h1>{{ article.title }}</h1>
            <p>
                <a href="{% url 'article:author_articles' article.author.username %}">{{ article.author.username }}</a>
                <span style="margin-left:20px" class="glyphicon glyphicon-thumbs-up">{{ total_likes }}like{{ total_likes|pluralize }}</span>
                <span style="margin-left:20px">{{ total_views }} view{{ total_views|pluralize}}</span>
            </p>
        </header>

        <link rel="stylesheet" href="{% static 'editor/css/editormd.preview.css' %}"/>
        <div id='editormd-view'>
        <textarea id="append-test" style="display:none;">
{{ article.body }}
        </textarea>
        </div>
        <div>
            <p class="text-center">
                <a onclick="like_article({{article.id}}, 'like')" href="#">
                    <span class="glyphicon glyphicon-thumbs-up">like</span>
                </a>
                <a onclick="like_article({{article.id}}, 'unlike')" href="#">
                    <span style="margin-left: 15px;" class="glyphicon glyphicon-thumbs-down">unlike</span>
                </a>
            </p>
        </div>
        <div>
            <p class="text-center"><strong>点赞本文的读者</strong></p>
            {% for user in article.users_like.all %}
            <p class="text-center">{{user.username}}</p>
            {% empty %}
            <p class="text-center">还没有人对此文章表态</p>
            {% endfor %}
        </div>
        <div>
            <h3><span class="glyphicon glyphicon-bullhorn"></span>本文有{{ comments.count }}评论</h3>
            {% for comment in article.comments.all %}
            <div>
                <p><strong>{{ comment.commentator }}</strong>说:</p>
                <p style="margin-left:40px;">{{ comment.body }}</p>
            </div>
            {% empty %}
            <p>没有评论</p>
            {% endfor %}

            <h3><span class="glyphicon glyphicon-send"></span>看文章,发评论,不要沉默</h3>
            <form action="." method="post" class="form-horizontal" role="form">{% csrf_token %}
                <div class="form-group">
                    <label for="inputEmail3" class="col-sm-2 control-label">评论员</label>
                    <div class="col-sm-10">
                        {{ comment_form.commentator}}
                    </div>
                </div>
                <div class="form-group">
                    <label for="inputEmail3" class="col-sm-2 control-label">评论</label>
                    <div class="col-sm-10">
                        {{ comment_form.body }}
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-sm-offset-2 col-sm-10">
                        <p><input type="submit" name="" value=" 发 评 论 " class="btn btn-primary"></p>
                    </div>
                </div>
            </form>
        </div>
    </div>

    <div class="col-md-3">
        <p class="text-center">
        <h3>最受欢迎文章</h3></p>
        <ol>
            {% for article_rank in most_viewed %}
            <li>
                <a href="{{article_rank.get_url_path}}">{{ article_rank.title }}</a>
            </li>
            {% endfor %}
        </ol>
    </div>
</div>

<script src='{% static "js/jquery.js" %}'></script>
<script src='{% static "editor/lib/marked.min.js" %}'></script>
<script src='{% static "editor/lib/prettify.min.js" %}'></script>
<script src='{% static "editor/lib/raphael.min.js" %}'></script>
<script src='{% static "editor/lib/underscore.min.js" %}'></script>
<script src='{% static "editor/lib/sequence-diagram.min.js" %}'></script>
<script src='{% static "editor/lib/flowchart.min.js" %}'></script>
<script src='{% static "editor/lib/jquery.flowchart.min.js" %}'></script>
<script src='{% static "editor/editormd.js" %}'></script>
<script type="text/javascript" src="{% static 'js/layer.js'%}"></script>
<script type="text/javascript">
$(function(){
    editormd.markdownToHTML("editormd-view", {
        htmlDecode: "style, script, iframe",
        emoji: true,
        taskList:true,
        tex:true,
        flowChart:true,
        sequenceDiagram : true,
    });
});

function like_article(id, action){
    $.ajax({
        url: "{% url 'article:like_article' %}",
        type: "POST",
        data: {"id":id, "action":action},
        success: function(e){
            if(e=="1"){
                layer.msg("感谢点赞");
                window.location.reload();
            }else{
                layer.msg("我会继续努力");
                window.location.reload();
            }
        },
    });
}

</script>
{% endwith %}
{% endblock %}

4、测试效果

打开文章详情,刷新页面,查看效果


文章详情
Gupao