6 功能4:文章详情页、点赞功能

1、文章详情页的设计

    # 文章详情页
    re_path(r'^(?P<username>\w+)/articles/(?P<article_id>\d+)$', views.article_detail, name='article_detail'),

2、文章详情页的数据构建

def article_detail(request, username, article_id):
    """文章详情页"""

    user_obj = models.UserInfo.objects.filter(username=username).first()
    blog = user_obj.blog        # 查询当前站点对象
    article_list = models.Article.objects.filter(user=user_obj)
    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(c=Count('article')).values_list('title','c')
    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 render(request,'blog/article_detail.html',{"username":username,'blog':blog,'article_list':article_list,"tag_list":tag_list,"date_list":date_list, "cate_list":cate_list})

1、解决复用问题:方式1:封装函数

3、解决复用问题:方式2:inclution_tag  自定义tag

1、自定义的simple_tag

 

 

2.inclution_tag 

 

 

# -*- coding: utf-8 -*-
# @Time    : 2018/08/04 0004 22:03
# @Author  : Venicid

from django import template
from django.db.models import Count
from blog import models

register = template.Library()


@register.simple_tag
def multi_tag(x,y):

    return x*y


@register.inclusion_tag("blog/classification.html")
def get_classification_style(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(c=Count('article')).values_list('title','c')
    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,"tag_list":tag_list,"date_list":date_list, "cate_list":cate_list}

 

4、标签字符串转义

def article_detail(request, username, article_id):
    """文章详情页"""
    user_obj = models.UserInfo.objects.filter(username=username).first()
    blog = user_obj.blog
    # article_id对应的文章
    article_obj = models.Article.objects.filter(pk=article_id).first()

    return render(request,'blog/article_detail.html',locals())

 

1、字符串转义

 

 

2、防止xss攻击

 

5、文章点赞

 1、样式构建

html
          <div id="div_digg">
                <div class="diggit" onclick="votePost(9420701,'Digg')">
                    <span class="diggnum" id="digg_count">1</span>
                </div>
                <div class="buryit" onclick="votePost(9420701,'Bury')">
                    <span class="burynum" id="bury_count">0</span>
                </div>
                <div class="clear"></div>
                <div class="diggword" id="digg_tips">你已经推荐过了
                </div>
            </div>

        #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;
        }
        #digg_tips{
            color: red;
            clear: both;
        }
css样式

 

 

 2、点赞事件绑定,

 

 

 

3、点赞的保存

url

    # 点赞
    re_path('^digg/$', views.digg, name='digg'),

 

 

 view视图

 

 

多次点赞报错

 

4、点赞数的数据同步

 

 5、点赞 提示,重复操作

 

 

 

6、点赞数的ajax更新

 

 

7、点赞的代码优化

 

 

8、代码

url

    # 点赞
    re_path('^digg/$', views.digg, name='digg'),

 

views

import json

def digg(request):
    """点赞视图"""
    # print(request.POST)
    article_id = request.POST.get("article_id")
    # article_id = request.POST.get("is_up")       # true
    is_up = json.loads(request.POST.get("is_up"))       # True
    user_id = request.user.pk       # 点赞人即为登录人

    # 点赞记录以及存在
    from django.http import JsonResponse  # Json数据返回到前端
    response = {"state":True, "msg":None, "handled":None}

    obj = models.ArticleUpDown.objects.filter(user_id=user_id,article_id=article_id).first()
    if not obj:
        # 创建一条点赞记录
        ard = models.ArticleUpDown.objects.create(user_id=user_id,is_up=is_up,article_id=article_id)
        from django.db.models import F
        # 点赞数的保存
        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("down_count") - 1)
    else:
        response['state']=False
        response['handled']= obj.is_up

    return JsonResponse(response)

 

 

点赞的模板层

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/bootstrap3/css/bootstrap.css">
    <script src="/static/js/jquery-3.2.1.min.js"></script>
    <style type="text/css">
        .glyphicon-comment {
            vertical-align: -1px;
        }

        #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;
        }

        #digg_tips {
            color: red;
            clear: both;
        }
    </style>
</head>
<body>


<div class="site-header">
    <nav class="navbar navbar-inverse">
        <div class="container-fluid">
            <div class="navbar-header">
                <a class="navbar-brand" href="#">
                    {{ blog.title }}
                </a>
            </div>
            <div class="navbar-header pull-right">
                <a class="navbar-brand" href="#">
                    管理
                </a>
            </div>
        </div>
    </nav>

</div>

<div class="container-fluid">
    <div class="row">
        <div class="col-md-3">
            {% load my_tags %}

            {% get_classification_style username %}
        </div>


        <div class="col-md-8">
            {% csrf_token %}
            <div class="article_info">
                <h3 class="text-center">{{ article_obj.title }}</h3>
                <div> {{ article_obj.content|safe }}</div>

                <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">0</span>
                    </div>
                    <div class="clear"></div>
                    <div class="diggword" id="digg_tips"></div>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
</html>
View Code

 

ajax

<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) {
                // 点赞 +1
                if (data.state) {
                    var val = parseInt($obj.text());
                    $obj.text(val+1)

                } else {

                    //点赞过了
                    var val=data.handled?"您已经推荐过了":"您已经反对过了"
                    $('#digg_tips').html(val)

                    setTimeout(function () {
                        $("#digg_tips").html("")
                    },2000)
                }
            }
        })
    })
</script>

 

 

 

 

 

 

 

 

  

 

posted @ 2018-08-04 22:58  venicid  阅读(500)  评论(0编辑  收藏  举报