• BBS-文章详情页、评论、评论树


     1、简单的实现评论功能

    article_detail.html,拿到数据  由路--给视图函数--写入数据库

      <p>评论内容:</p>
            <textarea name="" id="comment_content" cols="60" rows="10"></textarea>
            <p>
                <button class="btn btn-default comment_btn">提交评论</button>
            </p>
    url
    path("comment/", views.comment),

    --

     <script>
            $('.comment_btn').click(function () {
                {#根评论#}
                var pid='';
                var content=$('#comment_content').val();
                $.ajax({
                    url:'/comment/',
                    type:'post',
                    data:{  "csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val(),
                    'article_id':'{{ article_obj.pk }}','content':content ,'pid':pid},
                    success:function (data) {
                        console.log(data)
                    }
    
                })
            })

     ---

    def comment(request):
        """
        提交评论视图函数
        功能:
        1 保存评论
        2 创建事务
        3 发送邮件
        :param request:
        :return:
        """
        print(request.POST)
    
        article_id = request.POST.get("article_id")
        pid = request.POST.get("pid")
        content = request.POST.get("content")
        user_id = request.user.pk
        comment_obj=models.Comment.objects.create(user_id=user_id,article_id=article_id,content=content,parent_comment_id=pid)

     

    评论之后--清空评论框

     

     显示根评论的两种方法

    1、render显示根评论

     ---

    class="list-group

    article_detail.html

     <p>评论列表</p>
            <ul class="list-group comment_list">
                {% for comment in comment_list %}
                    <li class="list-group-item">
                        <div>
                            <a href=""># {{ forloop.counter }}楼</a> &nbsp;&nbsp;
                            <span>{{ comment.create_time|date:"Y-m-d H:i" }}</span>&nbsp;&nbsp;
                            <a href=""><span>{{ comment.user.username }}</span></a>
                            <a class="pull-right reply_btn" username="{{ comment.user.username }}"
                               comment_pk="{{ comment.pk }}">回复</a>
                        </div><div class="comment_con">
                            <p>{{ comment.content }}</p>
                        </div>
                    </li>
                {% endfor %}
            </ul>

     2、ajax显示评论:es6 模板字符串

    上一种方法评论后刷新才显示---用ajax评论就显示

     

    success:function (data) {
                        console.log(data);
    
                        var create_time = data.create_time;
                        var username=data.username;
                        var content=data.content;
    
                        // 构建标签字符串 es6语法
                         var s = `
                               <li class="list-group-item">
                                  <div>
    
                                      <span>${create_time}</span>&nbsp;&nbsp;
                                      <a href=""><span>${username}</span></a>
    
                                  </div>
                                  <div class="comment_con">
                                      <p>${content}</p>
                                  </div>
    
                                </li>`;
    
                            $("ul.comment_list").append(s);

    def comment():

     response={}
        response['create_time']=comment_obj.create_time.strftime("%Y-%m-%d %X")
        response['username']=request.user.username
        response['content']=content
      return JsonResponse(response)

     根评论

    {#    评论#}
        <div class="comments list-group">
            <p class="tree_btn">评论树</p>
            <div class="comment_tree">
            </div>
            <p>评论列表</p>
            <ul class="list-group comment_list">
                {% for comment in comment_list %}
                    <li class="list-group-item">
                        <div>
                            <a href=""># {{ forloop.counter }}楼</a> &nbsp;&nbsp;
                            <span>{{ comment.create_time|date:"Y-m-d H:i" }}</span>&nbsp;&nbsp;
                            <a href=""><span>{{ comment.user.username }}</span></a>
                            <a class="pull-right reply_btn" username="{{ comment.user.username }}"
                               comment_pk="{{ comment.pk }}">回复</a>
                        </div>
    
                        {% if comment.parent_comment_id %}
                            <div class="pid_info well">
                                <p>
                                    {{ comment.parent_comment.user.username }}: {{ comment.parent_comment.content }}
                                </p>
                            </div>
                        {% endif %}
                        <div class="comment_con">
                            <p>{{ comment.content }}</p>
                        </div>
                    </li>
                {% endfor %}
            </ul>
            <p>发表评论</p>
            <p>昵称:<input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50"
                         value="{{ request.user.username }}">
            </p>
            <p>评论内容:</p>
            <textarea name="" id="comment_content" cols="60" rows="10"></textarea>
            <p>
                <button class="btn btn-default comment_btn">提交评论</button>
            </p>
        </div>
    
        <script>
            $('.comment_btn').click(function () {
                {#根评论#}
                var pid='';
                var content=$('#comment_content').val();
                $.ajax({
                    url:'/comment/',
                    type:'post',
                    data:{  "csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val(),
                    'article_id':'{{ article_obj.pk }}','content':content ,'pid':pid},
                    success:function (data) {
                        console.log(data);
    
                        var create_time = data.create_time;
                        var username=data.username;
                        var content=data.content;
    
                        // 构建标签字符串 es6语法
                         var s = `
                               <li class="list-group-item">
                                  <div>
    
                                      <span>${create_time}</span>&nbsp;&nbsp;
                                      <a href=""><span>${username}</span></a>
    
                                  </div>
                                  <div class="comment_con">
                                      <p>${content}</p>
                                  </div>
    
                                </li>`;
    
                            $("ul.comment_list").append(s);
    
    
    
                        // 传回数据后,清空评论框中的内容
                        $('#comment_content').val('');
                    }
    
                })
            })
        </script>
    View Code

    3、子评论

    --

    --

      // 回复按钮事件
            $('.reply_btn').click(function () {
                $('#comment_content').focus();
                // 找父评论
                var val='@'+$(this).attr('username')+'
    ';
                $('#comment_content').val(val)
            })

     提交子评论

    根评论和子评论看是否点击回复

    --

    对样式进行改进

    子评论对内容进行处理

    清空pid

    # indexOf()
    定义和用法
    indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。
    语法
    stringObject.indexOf(searchvalue,fromindex)
    
    # slice()
    定义和用法
    slice() 方法可从已有的数组中返回选定的元素。
    语法
    arrayObject.slice(start,end)

     博客系统之render显示子评论

      {% if comment.parent_comment_id %}
                            <div class="pid_info well">
                                <p>
                                    {{ comment.parent_comment.user.username }}: {{ comment.parent_comment.content }}
                                </p>
                            </div>
                        {% endif %}

    博客系统之Ajax显示子评论的思路

     

    4、评论树

    1、评论树简介

    1、方式1:递归完成

    2、方式2:评论树展示数据

    2、评论树的请求数据

    {#    评论#}
        <div class="comments list-group">
            <p class="tree_btn">评论树</p>
            <div class="comment_tree">
            </div>
          {#-------评论树-------#}
            <script>
    
                     $.ajax({
                            url: "/get_comment_tree/",
                            type: "get",
                            data: {
                                article_id: "{{ article_obj.pk }}"
                            },
                            success: function (comment_list) {
                                console.log(comment_list);
    
                                $.each(comment_list, function (index, comment_object) {
    
                                    var pk = comment_object.pk;
                                    var content = comment_object.content;
                                    var parent_comment_id = comment_object.parent_comment_id;
                                    var s = '<div class="comment_item" comment_id=' + pk + '><span>' + content + '</span></div>';
    
                                    if (!parent_comment_id) {
    
                                        $(".comment_tree").append(s);
                                    } else {
                                        $("[comment_id=" + parent_comment_id + "]").append(s);
                                    }
                                })
                            }
                        })
                </script>

    视图函数

    def get_comment_tree(request):
        article_id=request.GET.get('article_id')
        ret=list(models.Comment.objects.filter(article_id=article_id).values('pk','content','parent_comment_id'))
        return JsonResponse(ret,safe=False)

    -----

    function (index, comment_object)
    函数中两个参数对应下图中的,一个索引,循环的元素对象

    博客系统之评论事务操作

     # 事务 from django.db import transaction
        with transaction.atomic():
            comment_obj=models.Comment.objects.create(user_id=user_id,article_id=article_id,content=content,parent_comment_id=pid)
            # 数据同步 F比较两个字段
            models.Article.objects.filter(pk=article_id).update(comment_count=F('comment_count')+1)

     博客系统之评论的邮件发送new

    别人对你的博客评论或者对你的评论进行评论,博客发邮件给你

    django中配置邮件 

    https://blog.csdn.net/xinxinnogiveup/article/details/78900811

    https://code.ziqiangxuetang.com/django/django-send-email.html

    1、settings配置

    # 发送邮件
    EMAIL_USE_SSL = True
    # EMIAL_HOST = 'smtp.exmail.qq.com'       # 如果是163 改成smtp.163.com
    EMAIL_HOST = 'smtp.qq.com'  # 如果是 163 改成 smtp.163.com
    EMAIL_PORT = 465            # 163的端口号是25
    EMAIL_HOST_USER = 'xxxxxxxx@qq.com'        # 账号
    EMAIL_HOST_PASSWORD = 'oXXXXXxxxxx'    # qq邮箱的授权码而不是密码
    DEFAULT_FROM_EMAIL = EMAIL_HOST_USER 

     # 发邮件
        from  django.core.mail import send_mail
        from cnblog import settings
        send_mail('您的文章%s新增了一条内容' % article_obj.title,content,
                                                     settings.EMAIL_HOST_USER,
                                                     ["xxxxxxx@qq.com"])

    加线程代码优化

    # 发邮件
        from django.core.mail import send_mail
        from cnblog import settings
        import threading
        t=threading.Thread(target=send_mail,args=('您的文章%s新增了一条内容' % article_obj.title,content,
                                                     settings.EMAIL_HOST_USER,
                                                     ["836342406@qq.com"]))
        t.start()

    整体代码

    url

     # 点赞
        path('digg/',views.digg),
    
        path("comment/", views.comment),
        # 获取评论树相关数据
        path("get_comment_tree/", views.get_comment_tree),
    
    
    
        # media
        re_path(r'media/(?P<path>.*)$',serve,{'document_root':settings.MEDIA_ROOT}),
    
        # 文章详情页
        # re_path('(?P<username>w)/(?P<article_id>d+)$',views.article_detail),
        re_path('^(?P<username>w+)/articles/(?P<article_id>d+)$', views.article_detail),
    
        # 关于个人站点的url
        re_path("^(?P<username>w+)/$", views.home_site),  # home_site(reqeust,username="yuan")
        #个人站点下的跳转
        re_path('^(?P<username>w+)/(?P<condition>tag|category|archive)/(?P<param>.*)/$', views.home_site),
        # home_site(reqeust,username="yuan",condition='tag',param='python')
    View Code

    settings

    LANGUAGE_CODE = 'en-us'
    
    
    # 时区选择
    # TIME_ZONE = 'UTC'
    TIME_ZONE = 'Asia/Shanghai'
    
    USE_I18N = True
    
    USE_L10N = True
    
    # 转换时区
    # USE_TZ = True
    USE_TZ = False
    
    
    
    # 发送邮件
    EMAIL_USE_SSL = True
    # EMIAL_HOST = 'smtp.exmail.qq.com'       # 如果是163 改成smtp.163.com
    EMAIL_HOST = 'smtp.qq.com'  # 如果是 163 改成 smtp.163.com
    EMAIL_PORT = 465
    EMAIL_HOST_USER = '@qq.com'        # 账号
    EMAIL_HOST_PASSWORD = 'xxxxxx'    # qq邮箱的授权码而不是密码
    DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
    View Code

    view视图

    from django.shortcuts import render
    
    # Create your views here.
    from django.shortcuts import render, HttpResponse,redirect
    
    # Create your views here.
    # 用户认证模块
    from django.contrib import auth
    from django.http import JsonResponse
    from blog.Myforms import UserForm
    from blog.models import UserInfo
    from blog import models
    import json
    from django.db.models import F
    from django.db import transaction
    from django.http import JsonResponse
    from django.db.models import Avg, Max, Min, Sum, Count
    from django.db import transaction
    def login(request):
        if request.method == 'POST':
            response = {'user': None, 'msg': None}
            user = request.POST.get('user')
            pwd = request.POST.get('pwd')
            # 读取验证码
            valid_code = request.POST.get('valid_code')
            # 回话跟踪技术,保存验证码
            valid_code_str = request.session.get('valid_code_str')
            # 如果书写的验证码和生成的验证码一致
            # 不区分大小写---可以统一变成大写
            if valid_code.upper() == valid_code_str.upper():
                user = auth.authenticate(username=user, password=pwd)
                if user:
                    auth.login(request, user)  # request.user==当前登录对象
                    response['user'] = user.username
                else:
                    response['msg'] = 'username or password error'
            else:
                response['msg'] = 'valid code error!'
            return JsonResponse(response)
        # ajax返回一个响应字符串
        return render(request, 'login.html')
    
    # 随机验证码
    def get_validCode_img(request):
        from blog.utils.validCode import get_valid_Code_img
        data = get_valid_Code_img(request)
        return HttpResponse(data)
    
    
    def index(request):
        article_list=models.Article.objects.all()
        return render(request, 'index.html', locals())
    
    def register(request):
        # 实例化 form 对象
    
        if request.is_ajax():
            print(request.POST)
            # 对传来的数据进行验证
            form = UserForm(request.POST)
            response = {'user': None, 'msg': None}
            if form.is_valid():
                response['user'] = form.cleaned_data.get('user')
                # 注册成功要把数据添加进数据库
                # 生成一条用户记录
                user = form.cleaned_data.get('user')
                pwd = form.cleaned_data.get('pwd')
                email = form.cleaned_data.get('email')
                avatar_obj = request.FILES.get('avatar')
                # if avatar_obj:
                #     user_obj = UserInfo.objects.create_user(username=user, password=pwd, email=email, avatar=avatar_obj)
                # else:
                #     user_obj = UserInfo.objects.create_user(username=user, password=pwd, email=email)
                extra = {}
                if avatar_obj:
                    extra["avatar"] = avatar_obj
    
                UserInfo.objects.create_user(username=user, password=pwd, email=email, **extra)
    
    
            else:
                print(form.cleaned_data)
                print(form.errors)
                response['msg'] = form.errors
                # 返回给Ajax
            return JsonResponse(response)
        form = UserForm()
        return render(request, 'register.html', locals())
    
    def logout(request):
        # request.session.flush()
        auth.logout(request)
        return redirect('/login/')
    
    
    
    def get_classification_data(username):
        user_obj = models.UserInfo.objects.filter(username=username).first()
        blog = user_obj.blog
        cate_list = models.Category.objects.filter(blog=blog).values('pk').annotate(c=Count('article__title')).values_list(
            'title', 'c')
        tag_list = models.Tag.objects.filter(blog=blog).values('pk').annotate(count=Count('article')).values_list('title',
                                                                                                                  'count')
        date_list = models.Article.objects.filter(user=user_obj).extra(
            select={'y_m_date': "date_format(create_time,'%%Y-%%m')"}).values('y_m_date').annotate(
            c=Count('nid')).values_list('y_m_date', 'c')
        return {"blog": blog, "cate_list": cate_list, "date_list": date_list, "tag_list": tag_list}
    
    def home_site(request,username,**kwargs):
        '''
        个人站点视图函数
        :param request:
        :return:
        '''
        user_obj=models.UserInfo.objects.filter(username=username).first()
    
        # 判断用户是否存在
        if not user_obj:
            return render(request,'not_found.html')
        blog = user_obj.blog
        print(blog)
    
        # 当前用户或者当前站点所对应文章
    
        # 方式一基于对象查询
        # 作者和文章的关系---> 一对多(文章)
        # article_list=user_obj.article_set.all()
        # 方式二 基于双下划线 __ 跨表查询
        article_list=models.Article.objects.filter(user=user_obj)
        # 判断是否跳转到其他地方
        # re_path("^(?P<username>w+)/(?P<condition>tag|category|archive)/(?P<param>.*)/$", views.home_site),
        if kwargs:
            condition = kwargs.get("condition")  # 标签分类归档
            param = kwargs.get("param")  # 具体的哪一个
            if condition == "category":
                article_list = article_list.filter(category__title=param)
            elif condition == "tag":
                article_list = article_list.filter(tags__title=param)
                print(article_list)
            else:
                year, month = param.split('-')
                print(year, month)
                article_list = article_list.filter(create_time__year=year,create_time__month=month)
                print(article_list)
    
    
    
        # 查询每一个分类名称以及对应的文章数
        # annotate(聚合函数(关联表__统计字段)).values("表模型的所有字段以及统计字段")
        # values('group by的字段')
        # ret=models.Category.objects.values('pk').annotate(c=Count('article__title')).values('title','c')
        # print(ret)
    
        # 查询当前站点的每一个分类名称以及对应的文章数
        cate_list=models.Category.objects.filter(blog=blog).values('pk').annotate(c=Count('article__title')).values_list('title','c')
        print(cate_list)
    
        # 每一个标签以及对应得文章数
        tag_list=models.Tag.objects.filter(blog=blog).values('pk').annotate(count=Count('article')).values_list('title','count')
        print('tag_list',tag_list)
    
        # 单表分组查询
        # 查询当前站点每一个年月的名称以及对应的文章数
        # 方式一
        date_list = models.Article.objects.filter(user=user_obj).extra(
            select={'y_m_date': "date_format(create_time,'%%Y-%%m')"}).values('y_m_date').annotate(
            c=Count('nid')).values_list('y_m_date', 'c')
        print(date_list)
    
        # 方式二
        from django.db.models.functions import TruncMonth
        #
        # date_list=models.Article.objects.filter(user=user_obj).annotate(month=TruncMonth('create_time')).values('month').annotate(c=Count('nid')).values_list('month','c')
        # print(date_list)
    
        return render(request, "home_site.html", locals())
    
    
    def article_detail(request,username,article_id):
        user_obj = models.UserInfo.objects.filter(username=username).first()
        blog = user_obj.blog
        cate_list = models.Category.objects.filter(blog=blog).values('pk').annotate(c=Count('article__title')).values_list(
            'title', 'c')
        tag_list = models.Tag.objects.filter(blog=blog).values('pk').annotate(count=Count('article')).values_list('title',
                                                                                                                  'count')
        date_list = models.Article.objects.filter(user=user_obj).extra(
            select={'y_m_date': "date_format(create_time,'%%Y-%%m')"}).values('y_m_date').annotate(
            c=Count('nid')).values_list('y_m_date', 'c')
    
        article_obj = models.Article.objects.filter(pk=article_id).first()
        comment_list = models.Comment.objects.filter(article_id=article_id)
        return render(request, "article_detail.html", locals())
    #     {'context':context,'blog':blog,'article_obj':article_obj,'comment_list':comment_list}
    
    
    def digg(request):
        print(request.POST)
        article_id=request.POST.get('article_id')
        # is_up=request.POST.get('is_up') # 字符串
        is_up=json.loads(request.POST.get('is_up')) # 字符串
        # 点赞人即当前登录人
        user_id=request.user.pk
    
        # 重复点赞和反对--都无效
        obj=models.ArticleUpDown.objects.filter(user_id=user_id,article_id=article_id).first()
        response={'state':True,'msg':None}
        if not obj:
            ard=models.ArticleUpDown.objects.create(user_id=user_id,article_id=article_id,is_up=is_up)
            queryset= models.Article.objects.filter(pk=article_id)
            if is_up:
                queryset.update(up_count=F('up_count')+1)
            else:
                queryset.update(down_count=F('up_count')+1)
    
        else:
            response['state']=False
            response['handled']=obj.is_up
        return JsonResponse(response)
    
    def comment(request):
        """
        提交评论视图函数
        功能:
        1 保存评论
        2 创建事务
        3 发送邮件
        :param request:
        :return:
        """
        print(request.POST)
    
        article_id = request.POST.get("article_id")
        pid = request.POST.get("pid")
        content = request.POST.get("content")
        user_id = request.user.pk
    
        article_obj=models.Article.objects.filter(pk=article_id).first()
        # 事务 from django.db import transaction
        with transaction.atomic():
            comment_obj=models.Comment.objects.create(user_id=user_id,article_id=article_id,content=content,parent_comment_id=pid)
            # 数据同步 F比较两个字段
            models.Article.objects.filter(pk=article_id).update(comment_count=F('comment_count')+1)
    
        response={}
        response['create_time']=comment_obj.create_time.strftime("%Y-%m-%d %X")
        response['username']=request.user.username
        response['content']=content
    
        # 发邮件
        from django.core.mail import send_mail
        from cnblog import settings
        import threading
        t=threading.Thread(target=send_mail,args=('您的文章%s新增了一条内容' % article_obj.title,content,
                                                     settings.EMAIL_HOST_USER,
                                                     ["836342406@qq.com"]))
        t.start()
    
        return JsonResponse(response)
    
    
    def get_comment_tree(request):
        article_id=request.GET.get('article_id')
        ret=list(models.Comment.objects.filter(article_id=article_id).values('pk','content','parent_comment_id'))
        return JsonResponse(ret,safe=False)
    View Code

    article_detail.html

    {% extends "base.html" %}
    
    {% block content %}
        {% csrf_token %}
    
        <div class="article_info">
            <h3 class="text-center title">{{ article_obj.title }}</h3>
            <div class="cont">
                {{ article_obj.content|safe }}
            </div>
    {#        博客园的点赞样式  ----#}
            <div class="">
                <div id="div_digg">
    {#                点赞#}
                    <div class="diggit action">
                        <span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span>
                    </div>
    {#                反对#}
                    <div class="buryit action">
                        <span class="burynum" id="bury_count">{{ article_obj.down_count }}</span>
                    </div>
                    <div class="clear"></div>
                    <hr>
                    <hr>
                    <div class="diggword" id="digg_tips" style="color: red;" ></div>
                </div>
    
            </div>
        </div>
    {#    点赞#}
          <script>
             $("#div_digg .action").click(function () {
                    var is_up = $(this).hasClass("diggit");
    
    
                    $obj = $(this).children("span");
    
                    $.ajax({
                        url: "/digg/",
                        type: "post",
                        data: {
                            "csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val(),
                            "is_up": is_up,
                            "article_id": "{{ article_obj.pk }}",
                        },
                        success: function (data) {
                            console.log(data);
    
                            if (data.state) {
                                var val = parseInt($obj.text());
                                $obj.text(val + 1);
                            }
                            else {
                                var val2 = data.handled ? "您已经推荐过!" : "您已经反对过!";
                                $("#digg_tips").html(val2);
    
                                setTimeout(function () {
                                    $("#digg_tips").html("")
                                }, 1000)
    
                            }
    
                        }
                    })
                });
        {#评论请求#}
            $('.comment_btn').click(function () {
                var content = $("#comment_content").val();
                $.ajax({
                    url:'/comment/',
                    type: 'post',
                    data: {  "csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val(),
                      "article_id": "{{ article_obj.pk }}",
                            "content": content,
                            pid: pid},
                    success:function (data) {
                        console.log(data)
                    }
                })
            })
    
        </script>
    
    
    
    {#    评论#}
        <div class="comments list-group">
            <p class="tree_btn">评论树</p>
            <div class="comment_tree">
    {#            <div comment_id="'1">#}
    {#                <span></span>#}
    {#            </div>#}
    {#            <div comment_id="'2">#}
    {#                <span></span>#}
    {#            </div>#}
    {#            <div comment_id="'3">#}
    {#                <span></span>#}
    {#            </div>#}
    
            </div>
          {#-------评论树-------#}
            <script>
    
    
                     $.ajax({
                            url: "/get_comment_tree/",
                            type: "get",
                            data: {
                                article_id: "{{ article_obj.pk }}"
                            },
                            success: function (comment_list) {
                                console.log(comment_list);
    
                                $.each(comment_list, function (index, comment_object) {
    
                                    var pk = comment_object.pk;
                                    var content = comment_object.content;
                                    var parent_comment_id = comment_object.parent_comment_id;
                                    var s = '<div class="comment_item" comment_id=' + pk + '><span>' + content + '</span></div>';
    
                                    if (!parent_comment_id) {
    
                                        $(".comment_tree").append(s);
                                    } else {
                                        $("[comment_id=" + parent_comment_id + "]").append(s);
                                    }
                                })
                            }
                        })
    
    
    
                </script>
    
    
            <p>评论列表</p>
            <ul class="list-group comment_list">
                {% for comment in comment_list %}
                    <li class="list-group-item">
                        <div>
                            <a href=""># {{ forloop.counter }}楼</a> &nbsp;&nbsp;
                            <span>{{ comment.create_time|date:"Y-m-d H:i" }}</span>&nbsp;&nbsp;
                            <a href=""><span>{{ comment.user.username }}</span></a>
                            <a class="pull-right reply_btn" username="{{ comment.user.username }}"
                               comment_pk="{{ comment.pk }}">回复</a>
                        </div>
    
                        {% if comment.parent_comment_id %}
                            <div class="pid_info well">
                                <p>
                                    {{ comment.parent_comment.user.username }}: {{ comment.parent_comment.content }}
                                </p>
                            </div>
                        {% endif %}
                        <div class="comment_con">
                            <p>{{ comment.content }}</p>
                        </div>
                    </li>
                {% endfor %}
            </ul>
            <p>发表评论</p>
            <p>昵称:<input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50"
                         value="{{ request.user.username }}">
            </p>
            <p>评论内容:</p>
            <textarea name="" id="comment_content" cols="60" rows="10"></textarea>
            <p>
                <button class="btn btn-default comment_btn">提交评论</button>
            </p>
        </div>
    
        <script>
    
            var pid='';
            $('.comment_btn').click(function () {
                {#根评论#}
                {#var pid='';#}
                var content=$('#comment_content').val();
    
                if(pid){
                    var index=content.indexOf('
    ');
                    content=content.slice(index+1)
                }
                $.ajax({
                    url:'/comment/',
                    type:'post',
                    data:{  "csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val(),
                    'article_id':'{{ article_obj.pk }}','content':content ,'pid':pid},
                    success:function (data) {
                        console.log(data);
    
                        var create_time = data.create_time;
                        var username=data.username;
                        var content=data.content;
    
                        // 构建标签字符串 es6语法
                         var s = `
                               <li class="list-group-item">
                                  <div>
    
                                      <span>${create_time}</span>&nbsp;&nbsp;
                                      <a href=""><span>${username}</span></a>
    
                                  </div>
                                  <div class="comment_con">
                                      <p>${content}</p>
                                  </div>
    
                                </li>`;
    
                            $("ul.comment_list").append(s);
    
    
    
                        // 传回数据后,清空评论框中的内容
                        $('#comment_content').val('');
                        pid=''
                    }
    
                })
            });
    
            // 回复按钮事件
    
            $('.reply_btn').click(function () {
                $('#comment_content').focus();
                // 找父评论
                var val='@'+$(this).attr('username')+'
    ';
                $('#comment_content').val(val)
                pid=$(this).attr('comment_pk')
            })
    
        </script>
    
    
    
    {% endblock %}
    View Code

    home_site.html

    {% extends  'base.html'%}
    {% block css %}
    
    {% endblock %}
    
    {% block content %}
    
         {#            文章样式#}
                <div class="article_list">
                       {% for article in article_list %}
                        <div class="article-item clearfix">
                            <h5><a href="/{{ article.user.username }}/articles/{{ article.pk }}">{{ article.title }}</a></h5>
                            <div class="article-desc">
                                {{ article.desc }}
                            </div>
                            <div class="small pub_info pull-right">
                                <span>发布于 &nbsp;&nbsp;{{ article.create_time|date:"Y-m-d H:i" }}</span>&nbsp;&nbsp;
                                <span class="glyphicon glyphicon-comment"></span>评论({{ article.comment_count }})&nbsp;&nbsp;
                                <span class="glyphicon glyphicon-thumbs-up"></span>点赞({{ article.up_count }})&nbsp;&nbsp;
                            </div>
                        </div>
                        <hr>
                        {% endfor %}
                </div>
    {% endblock %}
    View Code

    base.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    
        <style>
            * {
                margin: 0;
                padding: 0
            }
    
            .header {
                 100%;
                height: 60px;
                background-color: #369
            }
    
            .header .title {
                font-size: 18px;
                font-weight: 100;
                line-height: 60px;
                color: white;
                margin-left: 15px
            }
    
            .backend {
                float: right;
                margin-right: 15px;
                color: white;
                text-decoration: none;
            }
    
    
    .article_info .title{
       margin-bottom: 100px;
    }
    
            {% block css %}
    
            {% endblock %}
        </style>
    
        <link rel="stylesheet" href="/static/blog/bootstrap-3.3.7/css/bootstrap.css">
    
    {#    在base引入home_site 和 article_datail的样式#}
        <link rel="stylesheet" href="/static/css/article_detail.css" >
        <link rel="stylesheet" href="/static/css/home_site.css" >
    
        <script src="/static/JS/jquery-3.2.1.min.js"></script>
        <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
        <script src="/static/blog/bootstrap-3.3.7/js/bootstrap.min.js"></script>
    
    
    </head>
    <body>
    <div class="header">
        <div class="content">
            <p class="title">
                <span>{{ blog.title }}</span>
                <a href="" class="backend">管理</a>
            </p>
        </div>
    </div>
    <div class="container">
        <div class="row">
            <div class="col-md-3">
                <div class="panel panel-warning">
                    <div class="panel-heading">我的标签</div>
                    <div class="panel-body">
                        {% for tag in tag_list %}
                            <p><a href="/{{ username }}/tag/{{ tag.0 }}">{{ tag.0 }}({{ tag.1 }})</a></p>
                        {% endfor %}
                    </div>
                </div>
    
                <div class="panel panel-danger">
                    <div class="panel-heading">随笔分类</div>
                    <div class="panel-body">
                        {% for cate in cate_list %}
                            <p><a href="/{{ username }}/category/{{ cate.0 }}">{{ cate.0 }}({{ cate.1 }})</a></p>
                        {% endfor %}
                    </div>
                </div>
    
                <div class="panel panel-success">
                    <div class="panel-heading">随笔归档</div>
                    <div class="panel-body">
                        {% for date in date_list %}
                            <p><a href="/{{ username }}/archive/{{ date.0 }}">{{ date.0 }}({{ date.1 }})</a></p>
                        {% endfor %}
                    </div>
                </div>
    
            </div>
            <div class="col-md-9">
               {% block  content %}
    
                {% endblock %}
            </div>
        </div>
    </div>
    
    </body>
    </html>
    View Code
  • 相关阅读:
    函数三
    函数二
    函数一
    python数据类型和编码补充
    Python基础数据类型考试题
    VS2017设置C++标准
    std::weak_ptr
    Visual Assist 配色
    JMeter
    fcgi返回状态码
  • 原文地址:https://www.cnblogs.com/foremostxl/p/10012277.html
Copyright © 2020-2023  润新知