点赞与踩灭

img1

功能介绍:

1.当用户在登录状态下点击赞或者灭可以做相应的操作

2.点击赞过会显示"推荐成功",点击灭过会显示"反对成功"

3.重复操作会相示对应提示"您已经推荐过"或"您已经反对过"

4.使用Ajax实现

5.服务器端使用到的知识点:事务,ORM添加操作,ORM修改操作(F查询)

执行流程:

客户端遇到的问题:

1.如何点击一个div判断是赞还是灭操作,觖决方法为使用样式判断hasClass方法判断哪个标签中有相对应的样式类,hasClass返回布尔值,将返回值is_up,文章编号article_id,通过Ajax传递给服务器

2.服务器接收到传递的数据,进行处理(其中user.id)可以使用当前登录用户的iduser.pk,取得所有值后向数据库点赞表中添加一条新记录,点赞表使用联合组键如果重复添加会报错,这里可以使用try捕获下异常,同时在文章表中的相关字段也需要更新

3.添加数据,更新数据完成后,将标志位回传给浏览器这个可以根据个人定制,ret={'state':False,'flag':False},其中ret包含两个键值对 state:操作是否成功,True正常操作,False异常操作,flag:操作是否成功,True赞操作,False灭操作

4.浏览器接收到ret后进行判断如果state为真时再对flag进行判断,flag为真则显示点赞成功,否则点灭成功;state为假说明已经有点赞或者灭的操作,再对flag进行判断

5.在urls中添加一个路由

url(r"^poll/", views.poll, name="poll"),

代码部分

html代码

    <h3>{{ article_obj.title }}</h3>
    <div class="container-fluid">{{ article_obj.articledetail.content|safe }}</div>
    { % csr f_ token % }
    <div id="div_digg">
        <div class="digg diggit">
            <span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span>
        </div>
        <div class="digg buryit">
            <span class="burynum" id="bury_count">{{ article_obj.down_count }}</span>
        </div>

        <!-- 这个clesrfix是清除浮动的操作,bootstrap自带的样式 -->      
        <div class="clearfix"></div>

        <div class="diggword" id="digg_tips"></div>
    </div>
    <div class="clearfix"></div>
    <hr>

JS代码

$("#div_digg .digg").on('click', function () {

    if (username) {
        // 查看标签是否存在diggit样式返回bool值
        var is_up = $(this).hasClass("diggit");

        // is_up判断是点赞还是灭
        // article_id是当前文章id
        $.ajax({
            url: poll,
            type: "post",
            data: {
                is_up: is_up,
                article_id: article_id,
                csrfmiddlewaretoken: $("input[name='csrfmiddlewaretoken']").val()
            },
            success: function (data) {
                // 添加成功data.state为真
                if(data.state) {
                    // 操作为赞操作
                    if(data.flag){
                        $("#digg_count").html(parseInt(up_count)+1);
                        $("#digg_tips").text("推荐成功");
                    // 操作为灭操作
                    }else{
                        $("#bury_count").html(parseInt(down_count)+1);
                        $("#digg_tips").text("反对成功");
                    }
                // 添加失败data.state为假
                }else{
                    if(data.flag){
                        $("#digg_tips").text("您已经推荐过");
                    }else{
                        $("#digg_tips").text("您已经反对过");
                    }
                }
            }
        });
    } else {
        // 用户未登录
        window.location.href = "/logIn/";
    }
});

视图views

def poll(request):
    """
    点赞操作
    :param request:
    :return:
    """
    # ret两个键值对
    #   1.state:操作是否成功,True正常操作,False异常操作
    #   2.flag:操作是否成功,True赞操作,False灭操作
    ret = {'state': False,'flag':False}
    is_up = request.POST.get("is_up")
    # 取出的is_up为布尔值,需要转换
    is_up = json.loads(is_up)

    article_id = request.POST.get("article_id")

    # 用户ID可以直接取当前用户ID
    user_id = request.user.pk

    try:
        # 添加事务
        with transaction.atomic():
            # 向点赞表中添加数据,
            # 如果用户点赞,更新文章表up_count字段
            # 如果用户点灭,更新文章表down_count字段
            models.ArticleUpDown.objects.create(article_id=article_id, user_id=user_id, is_up=is_up)
            if is_up:
                # 返回值为影响的行数
                c = models.Article.objects.filter(pk=article_id).update(up_count=F("up_count") + 1)
                ret['flag'] = True
            else:
                c = models.Article.objects.filter(pk=article_id).update(down_count=F("down_count") + 1)

            ret['state'] = True

    except Exception as e:
        print(e)
        ret['flag'] = models.ArticleUpDown.objects.filter(article_id=article_id, user_id=user_id).first().is_up

    return JsonResponse(ret)

results matching ""

    No results matching ""