zoukankan      html  css  js  c++  java
  • 点赞模块示例

     

    点赞就是当前登录人

    一、流程分析:

      1 绑定事件
      2 携带data={article_id,is_up}发送Ajax请求
      3 对应的视图函数要生成一个赞或者灭记录
      4 响应结果给ajax
      5 Ajax的success处理

    二、功能实现

    点赞表

    class ArticleUpDown(models.Model):
        """
        点赞表
        """
        nid = models.AutoField(primary_key=True)
        user = models.ForeignKey(to="UserInfo", null=True)
        article = models.ForeignKey(to="Article", null=True)
        is_up = models.BooleanField(default=True)
    
        class Meta:
            unique_together = (("article", "user"),)
            verbose_name = "文章点赞"
            verbose_name_plural = verbose_name

    文章点赞模块article_detail.html 

    <div id="div_digg">
            <div class="diggit action">
                <span class="diggnum" id="digg_count">{{ article.up_count }}</span>
            </div>
            <div class="buryit action">
                <span class="burynum" id="bury_count">{{ article.down_count }}</span>
            </div>
            <div class="clear"></div>
            <div class="diggword" id="digg_tips" style="color: red;"></div>
        </div>
    <div class="info" article_id="{{ article.pk }}" username="{{ request.user.username }}"></div> {% csrf_token %} <script src="/static/js/article_detail.js"></script> 

    对应mystyle.css

    #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;
    }
    /*当属性设置float(浮动)时,他所在的物理位置已经脱离文档流了,但是大多时候我们希望文档流能识别float(浮动),
    或者是答希望float(浮动)后面的元素不被float(浮动)所影响,这个时候我们就需要用clear:both;来清除。*/

    1、绑定事件、携带data数据发送Ajax请求article_detail.js

    $("#div_digg .action").click(function () {
        // 判断用户是否登录,如果已经登录:
        if ($(".info").attr("username")) {
    
            // 点赞或踩灭
            var is_up = $(this).hasClass("diggit");
            var article_id = $(".info").attr("article_id");
    
            $.ajax({
                url: "/blog/up_down/",
                type: "post",
                data: {
                    //不用传user,因为用户只要登录就可以从request.user中取到
                    is_up: is_up,
                    article_id: article_id,
                    csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(),
                },
            })
        }
        // 如果用户没有登录,返回登录界面进行登录
        else {
            location.href = "/login/"
        }
    }); 

    2 对应的视图函数views.py,生成一个赞或者灭记录,把响应结果传给Ajax

        url(r"up_down/",views.up_down), 
    import json
    from django.db.models import F
    
    def up_down(request):
        print(request.POST)
        #有人点赞时传过来的值
        #<QueryDict: {'is_up': ['true'], 'article_id': ['6'],
        # 'csrfmiddlewaretoken': ['SL5W1m2Bb9fw5lsirkoEmB2wnvvWjMeSaE3WRxR6URkR0K9bDJCSto2fhVmAUOCa']}>
        article_id=request.POST.get('article_id')
        is_up=json.loads(request.POST.get('is_up'))
        #is_up在js中取出来的是布尔值,但是在前端当成键值以字符串的形式传过来
        #而is_up在数据库表中只能存TRUE or FALSE ,所以这里要把传过来的字符串通过json.loads转为python对象的布尔值
        user=request.user
        response={"state":True}
        print("is_up",is_up)      #is_up True
        try:
            #创建一条点赞记录
            models.ArticleUpDown.objects.create(user=user,article_id=article_id,is_up=is_up)
            #根据article_id找到点赞的那篇文章,更新点赞数
            models.Article.objects.filter(pk=article_id).update(up_count=F("up_count")+1)
    
        except Exception as e:
            response["state"]=False
            #第二次点此时user=user,article_id=article_id已经存在(联合唯一导致报错),取出里面的值(第一次存的)
            response["fisrt_action"]=models.ArticleUpDown.objects.filter(user=user,article_id=article_id).first().is_up
    
        return JsonResponse(response) 
        #return HttpResponse(json.dumps(response))

    3 Ajax拿到响应结果,进行success处理article_detail.js 

    success: function (data) {
            console.log(data);  //   {state: true}
    
            if (data.state) {// 赞或者灭成功
    
                if (is_up) {
                    //如果是赞取出赞的计数文本内容进行自加1然后赋值回去
                    var val = $("#digg_count").text();
                    val = parseInt(val) + 1;
                    $("#digg_count").text(val);
                } else {
                    var val = $("#bury_count").text();
                    val = parseInt(val) + 1;
                    $("#bury_count").text(val);
                }
            }
            else {    // 重复提交
    
                if (data.fisrt_action) {
                    $("#digg_tips").html("您已经推荐过");
                } else {
                    $("#digg_tips").html("您已经反对过");
                }
    
                setTimeout(function () {
                    $("#digg_tips").html("")
                }, 1000)
            }
        } 

    完整的article_detail.js文件

    $("#div_digg .action").click(function () {
        // 判断用户是否登录,如果已经登录:
        if ($(".info").attr("username")) {
    
            // 点赞或踩灭
            var is_up = $(this).hasClass("diggit");
            var article_id = $(".info").attr("article_id");
    
            $.ajax({
                url: "/blog/up_down/",
                type: "post",
                data: {
                    //不用传user,因为用户只要登录就可以从request.user中取到
                    is_up: is_up,
                    article_id: article_id,
                    csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(),
                },
                success: function (data) {
                    console.log(data);
    
    
                    if (data.state) {// 赞或者灭成功
    
                        if (is_up) {
                            var val = $("#digg_count").text();
                            val = parseInt(val) + 1;
                            $("#digg_count").text(val);
                        } else {
                            var val = $("#bury_count").text();
                            val = parseInt(val) + 1;
                            $("#bury_count").text(val);
                        }
                    }
                    else {    // 重复提交
    
                        if (data.fisrt_action) {
                            $("#digg_tips").html("您已经推荐过");
                        } else {
                            $("#digg_tips").html("您已经反对过");
                        }
    
                        setTimeout(function () {
                            $("#digg_tips").html("")
                        }, 1000)
                    }
                }
            })
    
        }
        // 如果用户没有登录,返回登录界面进行登录
        else {
            location.href = "/login/"
        }
    
    });
  • 相关阅读:
    a标签 不触发 目标链接
    java Byte[] to String(hex)
    error C2664: 'BOOL (PCERT_SELECT_STRUCT_A)' : cannot convert parameter 1 from 'CERT_SELECT_STRUCT *' to 'PCERT_SELECT_STRUCT_A'
    java jni c++ 例子
    Java.io.DataInputStream.readInt()
    sso demo mysql ( cas )
    sso demo 取消https (cas)
    poj 1422 Air Raid (二分匹配)
    poj 1274 The Perfect Stall (二分匹配)
    hdu 1392 Surround the Trees (凸包)
  • 原文地址:https://www.cnblogs.com/zh-xiaoyuan/p/12842307.html
Copyright © 2011-2022 走看看