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

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

时间:2023-01-04 22:55:35浏览次数:43  
标签:功能 obj 点赞点 文章 site num article pk

目录

仿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>
{#        文章评论楼结束#}
'''

标签:功能,obj,点赞点,文章,site,num,article,pk
From: https://www.cnblogs.com/zpf1107/p/17026245.html

相关文章