bbs03文章内容详细 评论功能讲解

 

 

仿bbs之侧边栏功能补充,点赞点踩功能,文章详细数据(内容)准备,文章评论功能部分讲解


  • 侧边栏筛选功能
  • 侧边栏封装
  • 文章详细数据准备
  • 点赞点踩样式搭建
  • 文章点赞点踩功能
  • 文章评论样式搭建
  • 文章根评论功能

 

侧边栏筛选功能

1.先研究博客园三种情况下的筛选
	分类筛选路由特性:		站点名称/category/数据主键值
    标签筛选路由特性:		站点名称/tag/数据主键值
    日期筛选路由特性:		站点名称/archive/文章年月
2.研究路由开设接口
	多个路由使用相同的视图函数 因为个人站点的文章和侧边栏筛选的文章互为父子集
'''
    # 侧边栏筛选功能接口
    # path('<str:username>/category/<int:category_id>', views.site_func),
    # path('<str:username>/tag/<int:tag_id>', views.site_func),
    # path('<str:username>/archive/<str:yearAndmonth>', views.site_func),
    # 上述三个路由可以合并成一个路由
    re_path('^(?P<username>\w+)/(?P<condition>category|tag|archive)/(?P<params>.*?)/', views.site_func),
    
    利用正则合并三个路由
'''
'''
后台判断筛选条件,进行再筛选,将再筛选的数据传到前端
'''
'''
前端绑定路由-根据路由的格式
'''

文章详情页搭建

1.路由的设计
	站点名称\article\文章数据主键值
    # 文章详情页
    path('<str:username>/article/<int:article_id>/', views.article_detail_func),
    
def article_detail_func(request, username, article_id):
    # 1.筛选某篇具体的文章对象
    article_obj = models.Article.objects.filter(site__site_name=username).filter(pk=article_id).first()
    site_obj = models.Site.objects.filter(site_name=username).first()
    '''这里也可以添加健壮性校验 防止用户自己瞎点'''
    if not article_obj:
        return HttpResponse('你瞎点李奶奶呢')
    return render(request, 'articleDetailPage.html', locals())
由于一份代码使用了两次,程序员的直觉告诉我不能这么做,于是我将代码写入一个自定义标签py文件
from django import template
from app01 import models
from django.db.models import Count
from django.db.models.functions import TruncMonth

register = template.Library()


@register.inclusion_tag('leftmenu.html', name='mymenu')
def index(username):
    site_obj = models.Site.objects.filter(site_name=username).first()
    # 查询个人站点下所有的分类名称以及每个分类下的文章数
    category_queryset = models.Category.objects.filter(site=site_obj).annotate(article_num=Count('article__pk')).values(
        'name', 'article_num', 'pk'
    )
    # print(category_queryset)  # <QuerySet [{'name': 'tony的分类1', 'article_num': 1}, {'name': 'tony的分类2', 'article_num
    # ': 2}, {'name': 'tony的分类3', 'article_num': 2}]>
    # 查询个人站点下所有的标签名称以及每个标签下的文章数
    tag_queryset = models.Tag.objects.filter(site=site_obj).annotate(article_num=Count('article__pk')).values(
        'name', 'article_num', 'pk'
    )
    # 年月分组并统计文章个数
    date_queryset = models.Article.objects.filter(site=site_obj).annotate(month=TruncMonth('create_time')).values('month').annotate(
        article_num=Count('pk')).values('month', 'article_num')
    return locals()

新建html页面继承home并写入自定义标签

然后在文章标题的a标签内动态填写路由即可

/{{ article_obj.site.userinfo.username }}/article/{{ article_obj.pk }}/

文章详细数据准备

检查网页源码,找到cnblogs_post_body标签,复制html数据,然后填入文章详细内容,然后在前端展示页|safe

点赞点踩样式搭建

1.直接拷贝博客园样式即可 主要除了html还有css
'''
css
    <style>
        #div_digg {
            float: right;
            margin-bottom: 10px;
            margin-right: 30px;
            font-size: 12px;
            width: 125px;
            text-align: center;
            margin-top: 10px;
        }

        .diggit {
            float: left;
            width: 46px;
            height: 52px;
            background: url('/static/img/upup.gif') no-repeat;
            text-align: center;
            cursor: pointer;
            margin-top: 2px;
            padding-top: 5px;
        }

        .buryit {
            float: right;
            margin-left: 20px;
            width: 46px;
            height: 52px;
            background: url('/static/img/downdown.gif') no-repeat;
            text-align: center;
            cursor: pointer;
            margin-top: 2px;
            padding-top: 5px;
        }

        .clear {
            clear: both;
        }

        .diggword {
            margin-top: 5px;
            margin-left: 0;
            font-size: 12px;
            color: #808080;
        }
    </style>
'''
'''
html
        <div class="clearfix">
            <div id="div_digg">
                <div class="diggit upordown">
                    <span class="diggnum" id="digg_count">{{ article_obj.up_num }}</span>
                </div>
                <div class="buryit upordown">
                    <span class="burynum" id="bury_count">{{ article_obj.down_num }}</span>
                </div>

                <div class="clear"></div>
                <span style="color: red" id="d1"></span>
                <div class="diggword" id="digg_tips">
                </div>
            </div>
        </div>
'''

2.针对路由匹配
	含有动态匹配的路由很多时候可能会出现顶替的情况
    这个时候我们可以将简单的路由放在前面 复杂的放在后面 甚至修改匹配策略

def up_or_down_func(request):
    """
    1.校验用户是否登录
    2.校验当前文章是否是当前用户自己的
    3.校验当前文章是否已被当前用户点过
    4.创建点赞点踩记录(不要忘记文章表中的优化字段 同步自增)
    """
    back_dict = {'code': 10000, 'msg': ''}
    # 根据post请求获取数据
    if request.method == 'POST':
        # 1.校验用户是否登录
        if request.user.is_authenticated:
            is_up = request.POST.get('is_up')
            article_pk = request.POST.get('article_pk')  # true <class 'str'>
            # 文章对象
            article_obj = models.Article.objects.filter(pk=article_pk).first()
            # 2.校验当前文章是否是当前用户自己的
            if not article_obj.site.userinfo == request.user:
                # 当前文章和当前用户是否已存在
                is_click = models.UpAndDown.objects.filter(user=request.user, article=article_obj)
                # 3.校验当前文章是否已被当前用户点过
                if not is_click:
                    # 4.创建点赞点踩记录(不要忘记文章表中的优化字段 同步自增)
                    is_up = json.loads(is_up)  # 自动转换成python中布尔值
                    if is_up:
                        # 先将文章表中的优化评论数量字段自增1
                        models.Article.objects.filter(pk=article_pk).update(up_num=F('up_num') + 1)
                        back_dict['msg'] = '点赞成功'
                    else:
                        models.Article.objects.filter(pk=article_pk).update(down_num=F('down_num') + 1)
                        back_dict['msg'] = '点踩成功'
                    # 创建点赞点踩表中的数据
                    models.UpAndDown.objects.create(user=request.user, article=article_obj, is_up=is_up)
                else:
                    back_dict['code'] = 10001
                    back_dict['msg'] = '您已经点过赞了'
            else:
                back_dict['code'] = 10002
                back_dict['msg'] = '你不能给自己点赞'
        else:
            back_dict['code'] = 10003
            back_dict['msg'] = '请先<a href="/login/">登录</a>'
        return JsonResponse(back_dict)

文章点赞点踩样式
    <div class="clearfix">
            <div id="div_digg">
                <div class="diggit upordown">
                    <span class="diggnum" id="digg_count">{{ article_obj.up_num }}</span>
                </div>
                <div class="buryit upordown">
                    <span class="burynum" id="bury_count">{{ article_obj.down_num }}</span>
                </div>

                <div class="clear"></div>
                <span style="color: red" id="d1"></span>
                <div class="diggword" id="digg_tips">
                </div>
            </div>
        </div>
        
 
ajax请求:
'''
    <script>
        // 给点赞点踩图标绑定点击事件
        $('.upordown').click(function () {
            // 提前将当前点击对象存起来
            let upOrDown = $(this);
            let isUP = $(this).hasClass('diggit')  // 判断标签是否含有某个class值 从而二选一区分赞和踩
            // 发送ajax请求
            $.ajax({
                url: '/up_or_down/',
                type: 'post',
                data: {
                    'csrfmiddlewaretoken': '{{ csrf_token }}',
                    'article_pk': {{ article_obj.pk }},
                    'is_up': isUP,
                },
                success:function (args) {
                    if (args.code === 10000){
                        {#upOrDown.find('span').text(Number(upOrDown.find('span').text()) + 1)#}
                        upOrDown.children().first().text(Number( upOrDown.children().first().text()) + 1)
                    }
                    $('#d1').html(args.msg)
                }
            })

        })
    </script>
'''

文章评论功能

1.前端样式搭建
{#    文章评论样式开始#}
    <div class="comment-area">
    <p><span class="glyphicon glyphicon-comment"></span>发表评论</p>
        <textarea name="" id="" cols="30" rows="10" class="form-control"></textarea>
        <button class="btn btn-primary">提交评论</button>

    </div>

{#    文章评论样式结束#}

2.评论逻辑
	先考虑根评论 之后再考虑子评论 不要乱!!!
3.根评论
	点击提交评论按钮 发送ajax请求 携带必要的参数即可
    path('comment/', views.comment_func),
    
    '''
    @login_required
def comment_func(request):
    back_dict = {'code': 10000, 'msg': ''}
    if request.method == 'POST':
        article_pk = request.POST.get('article_pk')
        content = request.POST.get('content')
        # 文章内优化字段评论数自增1
        models.Article.objects.filter(pk=article_pk).update(comment_num=F('comment_num') + 1)
        # 在文章表内创建评论与文章主键值与用户主键值
        models.Comment.objects.create(user=request.user, article_id=article_pk, content=content)
        back_dict['msg'] = '评论成功'
        return JsonResponse(back_dict)
        '''
    
'''
        // 给提交评论按钮绑定点击事件
        $('#commentBtn').click(function () {
            $.ajax({
                url: '/comment/',
                type: 'post',
                data: {
                    'csrfmiddlewaretoken': '{{ csrf_token }}',
                    'article_pk': '{{ article_obj.pk }}',
                    'content': $('#comment').val(),
                },
                success: function (args) {

                }
            })
        })
'''

'''
{#        文章评论楼开始#}
        <div class="comment_list">
        <ul class="list-group">
            {% for comment_obj in comment_list %}
{#                span标签自增楼层#}
            <li class="list-group-item">
                <span><a href="#">#{{ forloop.counter }}楼</a></span>
                <span>{{ comment_obj.comment_time|date:'Y-m-d H:i' }}</span>
                <span><a href="/{{ comment_obj.user.username }}/">{{ comment_obj.user.username }}</a></span>
                <p>
                    {{ comment_obj.content }}
                </p>
            </li>

            {% endfor %}
        </ul>

            
        </div>
{#        文章评论楼结束#}
'''

posted @   小福福  阅读(62)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
  1. 1 原来你也在这儿 温余福
  2. 2 世间美好和你环环扣扣 温余福
  3. 3 随风起舞 温余福
  4. 4 罪恶都市 温余福
世间美好和你环环扣扣 - 温余福
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 尹初七

作曲 : 温余福

编曲 : 彭圣杰

偏偏秉烛夜游

偏偏秉烛夜游

午夜星辰 似奔走之友

爱你每个结痂伤口

酿成的陈年烈酒

入喉尚算可口

入喉尚算可口

怎么泪水 还偶尔失守

邀你细看心中缺口

裂缝中留存 温柔

此时已莺飞草长 爱的人正在路上

此时已莺飞草长 爱的人正在路上

我知他风雨兼程 途经日暮不赏

穿越人海 只为与你相拥

此刻已皓月当空 爱的人手捧星光

我知他乘风破浪 去了黑暗一趟

感同身受 给你救赎热望

知道你不能 还要你感受

知道你不能 还要你感受

让星光加了一点彩虹

让樱花偷偷 吻你额头

让世间美好 与你环环相扣

此时已莺飞草长 爱的人正在路上

此时已莺飞草长 爱的人正在路上

我知他风雨兼程 途经日暮不赏

穿越人海 只为与你相拥

此刻已皓月当空 爱的人手捧星光

我知他乘风破浪 去了黑暗一趟

感同身受 给你救赎热望

此时已莺飞草长 爱的人正在路上

此时已莺飞草长 爱的人正在路上

我知他风雨兼程 途经日暮不赏

穿越人海 只为与你相拥

此刻已皓月当空 爱的人手捧星光

我知他乘风破浪 去了黑暗一趟

感同身受 给你救赎热望

知道你不能 还要你感受

知道你不能 还要你感受

让星光加了一点彩虹

当樱花开的纷纷扬扬

当世间美好 与你环环相扣

特别鸣谢:槿葵,我们的海报制作妹妹。

原唱:柏松

吉他:柏松

和声:柏松

录音:柏松

混音:张强

点击右上角即可分享
微信分享提示