django框架前后端混合项目之侧边栏及点赞点踩功能等相关内容-80

1 侧边栏展示

#查询当前站点下所有分类下的文章数
# python是解释型语言,做垃圾回收
# python的cpython解释器存在,jpython ,pypy

### 三个分组查询
res_category =models.Category.objects.filter(blog=user.blog).annotate(num=Count('article__id')).values_list('name', 'num', 'id')
res_tag =models.Tag.objects.filter(blog=user.blog).annotate(num=Count('article__id')).values_list('name','num', 'id')
res_month =models.Article.objects.filter(blog=user.blog).annotate(month=TruncMonth('create_time')).values(
'month').annotate(c=Count('id')).order_by('-month').values_list('month', 'c')


### 根据年月分组的分析过程
id      create_time                month          
1 2020-09-29 11:59:01.326770    2020-09    2
2 2020-09-29 11:59:37.299591    2020-09


3 2020-10-29 09:59:53.029608    2020-10    4
4 2020-10-29 12:00:11.200812    2020-10
5 2020-10-29 12:00:26.995485    2020-10
10 2020-10-30 09:45:14.887788    2020-10

8 2020-08-01 09:03:16.000000    2020-08    2
9 2020-08-01 09:24:24.000000    2020-08


models.Article.objects.filter(blog=user.blog).annotate(month=TruncMonth('create_time'))
.values('month').annotate(c=Count('id')).values_list('month', 'c')

页面样式

<div>
   <div class="panel panel-danger">
       <div class="panel-heading">
           <h3 class="panel-title">我的标签</h3>
       </div>
       <div class="panel-body">
          {% for tag in res_tag %}
               <p><a href="/{{ name }}/tag/{{ tag.2 }}.html">{{ tag.0 }}({{ tag.1 }})</a></p>
          {% endfor %}
       </div>
   </div>
   <div class="panel panel-info">
       <div class="panel-heading">
           <h3 class="panel-title">随笔分类</h3>
       </div>
       <div class="panel-body">
          {% for category in res_category %}

               <p><a href="/{{ name }}/category/{{ category.2 }}.html">{{ category.0 }}({{ category.1 }})</a></p>
          {% endfor %}


       </div>
   </div>
   <div class="panel panel-info">
       <div class="panel-heading">
           <h3 class="panel-title">随笔档案</h3>
       </div>
       <div class="panel-body">
          {% for month in res_month %}
               <p>
                   <a href="/{{ name }}/archive/{{ month.0|date:'Y/m' }}.html">{{ month.0|date:'Y年m月' }}({{ month.1 }})</a>
               </p>
          {% endfor %}
       </div>
   </div>
</div>

2 侧边栏筛选

路由

re_path('^(?P<name>w+)/(?P<query>category|tag|archive)/(?P<condition>.*).html$', views.site),

 

页面

<div>
   <div class="panel panel-danger">
       <div class="panel-heading">
           <h3 class="panel-title">我的标签</h3>
       </div>
       <div class="panel-body">
          {% for tag in res_tag %}
               <p><a href="/{{ name }}/tag/{{ tag.2 }}.html">{{ tag.0 }}({{ tag.1 }})</a></p>
          {% endfor %}
       </div>
   </div>
   <div class="panel panel-info">
       <div class="panel-heading">
           <h3 class="panel-title">随笔分类</h3>
       </div>
       <div class="panel-body">
          {% for category in res_category %}

               <p><a href="/{{ name }}/category/{{ category.2 }}.html">{{ category.0 }}({{ category.1 }})</a></p>
          {% endfor %}


       </div>
   </div>
   <div class="panel panel-info">
       <div class="panel-heading">
           <h3 class="panel-title">随笔档案</h3>
       </div>
       <div class="panel-body">
          {% for month in res_month %}
               <p>
                   <a href="/{{ name }}/archive/{{ month.0|date:'Y/m' }}.html">{{ month.0|date:'Y年m月' }}({{ month.1 }})</a>
               </p>
          {% endfor %}
       </div>
   </div>
</div>

视图

def site(request, name, **kwargs):
   # 分三种情况(根据标签过滤,根据分类过滤,根据时间过滤)
   user = models.UserInfo.objects.filter(username=name).first()
   if user:
       article_list = user.blog.article_set.all()
       # 根据不同情况对article_list进行过滤,article_list是queryset对象,可以继续filter
       query = kwargs.get('query', None)
       if query == 'category':  # 说明走的是过滤的路由
           condition = kwargs.get('condition')
           article_list = article_list.filter(category_id=condition)
       elif query == 'tag':
           condition = kwargs.get('condition')
           article_list = article_list.filter(tag__id=condition)
       elif query == 'archive':
           year, month = kwargs.get('condition').split('/')  # 2020/09
           article_list = article_list.filter(create_time__year=year, create_time__month=month)

       res_category = models.Category.objects.filter(blog=user.blog).annotate(num=Count('article__id')).values_list(
           'name', 'num', 'id')
       res_tag = models.Tag.objects.filter(blog=user.blog).annotate(num=Count('article__id')).values_list('name',
                                                                                                          'num', 'id')
       res_month = models.Article.objects.filter(blog=user.blog).annotate(month=TruncMonth('create_time')).values(
           'month').annotate(c=Count('id')).order_by('-month').values_list('month', 'c')

       return render(request, 'site.html', locals())
   else:
       return render(request, 'error.html')

3 侧边栏inclusion_tag

# 步骤
-在app下创建一个包,templatetags
   -任意新建一个py文件my_tag.py
   -导入library
   register = library.Library()
   -写一个函数,使用inclusion_tag装饰
   @register.inclusion_tag('left.html')
def left(username):
   user = models.UserInfo.objects.filter(username=username).first()
   res_category = models.Category.objects.filter(blog=user.blog).annotate(num=Count('article__id')).values_list(
       'name', 'num', 'id')
   res_tag = models.Tag.objects.filter(blog=user.blog).annotate(num=Count('article__id')).values_list('name',
                                                                                                      'num', 'id')
   res_month = models.Article.objects.filter(blog=user.blog).annotate(month=TruncMonth('create_time')).values(
       'month').annotate(c=Count('id')).order_by('-month').values_list('month', 'c')

   return {'name':username,'res_category': res_category, 'res_tag': res_tag, 'res_month': res_month}

   -写一个模板
   <div>
   <div class="panel panel-danger">
       <div class="panel-heading">
           <h3 class="panel-title">我的标签</h3>
       </div>
       <div class="panel-body">
          {% for tag in res_tag %}
               <p><a href="/{{ name }}/tag/{{ tag.2 }}.html">{{ tag.0 }}({{ tag.1 }})</a></p>
          {% endfor %}
       </div>
   </div>
   <div class="panel panel-info">
       <div class="panel-heading">
           <h3 class="panel-title">随笔分类</h3>
       </div>
       <div class="panel-body">
          {% for category in res_category %}

               <p><a href="/{{ name }}/category/{{ category.2 }}.html">{{ category.0 }}({{ category.1 }})</a></p>
          {% endfor %}


       </div>
   </div>
   <div class="panel panel-info">
       <div class="panel-heading">
           <h3 class="panel-title">随笔档案</h3>
       </div>
       <div class="panel-body">
          {% for month in res_month %}
               <p>
                   <a href="/{{ name }}/archive/{{ month.0|date:'Y/m' }}.html">{{ month.0|date:'Y年m月' }}({{ month.1 }})</a>
               </p>
          {% endfor %}
       </div>
   </div>
</div>

-使用,在指定的位置
  {% load mytag %}
        {% left name %}

   

 

4 点赞点踩样式

html

<div id="div_digg">
   <div class="diggit action">
       <span class="diggnum" id="digg_count">{{ article.up_num }}</span>
   </div>
   <div class="buryit action">
       <span class="burynum" id="bury_count">{{ article.down_num }}</span>
   </div>
   <div class="clear"></div>
   <div class="diggword" id="digg_tips" style="color: red;">
   </div>
</div>

css

#div_digg {
   float: right;
   margin-bottom: 10px;
   margin-right: 30px;
   font-size: 12px;
    125px;
   text-align: center;
   margin-top: 10px;
}

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

.buryit {
   float: right;
   margin-left: 20px;
    46px;
   height: 52px;
   background: url(/static/img/down.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;
}

5 点赞点踩功能完成

js

<script>
   $(".action").click(function () {
       var is_up = $(this).hasClass('diggit')
       var span = $(this).children('span')
       $.ajax({
           url: '/upanddown/',
           method: 'post',
           data: {
               article_id: '{{ article.id }}',
               is_up: is_up,
               csrfmiddlewaretoken: '{{ csrf_token }}'
          },
           success: function (data) {
               console.log(data)
               $('#digg_tips').html(data.msg)
               if (data.code == 100) {
                   //点赞或者点踩的数字加一
                   var num = Number(span.html()) + 1
                   span.html(num)
              }

          }
      })

  })
</script>

后端

def upanddown(request):
   res = {'code': 100, 'msg': ''}
   if request.user.is_authenticated:
       # article表中数字加1,在点赞点踩表中记录一条
       # 这个人对该文章只能点赞或者点踩一次
       # 先查一下,如果有记录了,就不能再点了
       article_id = request.POST.get('article_id')
       user_id = request.user.id
       is_up = request.POST.get('is_up')  # is_up是一个字符串
       print(type(is_up))
       # if is_up=='true':
       #     is_up=True
       # else:
       #     is_up = False
       is_up=json.loads(is_up)
       print(type(is_up))
       res_1 = models.UpAndDown.objects.filter(article_id=article_id, user_id=user_id).count()
       if res_1:
           res['code'] = 101
           res['msg'] = '已经点过了'
       else:
           with transaction.atomic():
               models.UpAndDown.objects.create(article_id=article_id, user_id=user_id, is_up=is_up)
               if is_up:
                   models.Article.objects.filter(pk=article_id).update(up_num=F('up_num') + 1)
                   res['msg'] = '点赞成功'
               else:
                   models.Article.objects.filter(pk=article_id).update(down_num=F('down_num') + 1)
                   res['msg'] = '点踩成功'

   else:
       res['code'] = 109
       res['msg'] = '请先<a href="/login/">登录</a>'
   return JsonResponse(res)
原文地址:https://www.cnblogs.com/usherwang/p/14217601.html