基于Django框架利用Ajax实现点赞功能实例代码

概要:

要实现点赞功能,需要实现的有:谁进行的点赞、什么时候进行点赞、点赞的对象是谁、每一个对象的点赞数量是多少、点赞过后还需要能够取消点赞,为了是点赞后的信息能够及时的显示在前端页面,就需要使用Ajax来异步请求数据,实现实时显示。

下面话不多说了,来随着小编一起看看详细的介绍吧

模型分析:

创建的模型需要记录的数据有:点赞者、点赞对象、点赞时间、点赞的数量,由于前面三个属性主要用于记录点赞的状态,而点赞数量主要用于记录某篇文章的点赞数量,所以这里最好把点赞数量单独放在一个模型中。这里就创建了两个模型,LikeRecord和LIkeCount,LikeRecord用于记录点赞状态,LIkeCount用于记录点赞的数量。大致的思路图:

代码:

from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import User

# Create your models here.

# 用于记录点赞数量的模型
class LikeCount(models.Model):
 content_type = models.ForeignKey(ContentType, on_delete=models.DO_NOTHING)
 object_id = models.PositiveIntegerField()
 content_object = GenericForeignKey('content_type', 'object_id')
 # 用于记录点赞数量的字段
 like_num = models.IntegerField(default=0)

# 用于记录点赞状态的模型
class LikeRecord(models.Model):
 content_type=models.ForeignKey(ContentType, on_delete=models.DO_NOTHING)
 object_id=models.PositiveIntegerField()
 content_object=GenericForeignKey('content_type', 'object_id')
 # 记录点赞的用户
 like_user = models.ForeignKey(User, on_delete=models.DO_NOTHING)
 # 记录点赞的时间
 like_time = models.DateTimeField(auto_now_add=True)

视图函数:

视图函数主要的作用就是接受前端通过Ajax发送回来的数据,并且对数据进行判断处理,然后对前面的两个模型进行实例化操作已经数据变更操作,当数据成功过后返回处理后的结果,当数据存在错误时,返回相应的提示信息。

代码:

from django.shortcuts import render, HttpResponseRedirect
from django.contrib.contenttypes.models import ContentType
from django.http import JsonResponse
from .models import LikeCount, LikeRecord

# Create your views here.

# 数据操作成功返回数据方法
def success_response(like_num):
 data = {}
 data['status'] = 'SUCCESS'
 data['like_num'] = like_num
 return JsonResponse(data)

# 数据操作失败返回信息的方法
def error_response(message):
 data = {}
 data['status'] = 'ERROR'
 data['message'] = message
 return JsonResponse(data)

def like_up(request):
 # 得到GET中的数据以及当前用户
 user = request.user
 # 判断用户是否登录
 if not user.is_authenticated:
  return error_response('未登录,不能进行点赞操作')
 content_type = request.GET.get('content_type')
 content_type = ContentType.objects.get(model=content_type)
 object_id = request.GET.get('object_id')
 is_like = request.GET.get('is_like')

 # 创建一个点赞记录
 if is_like == 'true':
  # 进行点赞,即实例化一个点赞记录
  like_record, created = LikeRecord.objects.get_or_create(content_type=content_type, object_id=object_id, like_user=user)
  # 通过created来判断点赞记录是否存在,如果存在则不进行点赞,如果不存在则进行点赞数量加一
  if created:
   # 不存在点赞记录并且已经创建点赞记录,需要将点赞数量加一
   like_count, created = LikeCount.objects.get_or_create(content_type=content_type, object_id=object_id)
   like_count.like_num += 1
   like_count.save()
   return success_response(like_count.like_num)
  else:
   # 已经进行过点赞
   return error_response('已经点赞过')
 else:
  # 取消点赞
  # 先查询数据是否存在,存在则进行取消点赞
  if LikeRecord.objects.filter(content_type=content_type, object_id=object_id, like_user=user).exists():
   # 数据存在,取消点赞
   # 删除点赞记录
   LikeRecord.objects.get(content_type=content_type, object_id=object_id, like_user=user).delete()
   # 判断对应的点赞数量数据是否存在,如果存在则对点赞数量进行减一
   like_count, create = LikeCount.objects.get_or_create(content_type=content_type, object_id=object_id)
   if create:
    # 数据不存在,返回错误信息
    return error_response('数据不存在,不能取消点赞')
   else:
    # 数据存在,对数量进行减一
    like_count.like_num -= 1
    like_count.save()
    return success_response(like_count.like_num)
  else:
   # 数据不存在,不能取消点赞
   return error_response('数据不存在,不能取消点赞')

Ajax代码:

该段代码的主要作用:通过前端按钮触动相应的处理函数,将当前的数据传递给后端,后端接受数据后进行处理,处理完后的数据再返回给前端,通过Ajax实时显示到前端。

代码:

<script type="text/javascript">
 function change_like(obj, content_type, object_id) {
  // 判断obj中是否包含active的元素,用于判断当前状态是否为激活状态
  var is_like = obj.getElementsByClassName('active').length == 0
  $.ajax({
   url: '/like_up/',
   // 为了避免加入csrf_token令牌,所以使用GET请求
   type: 'GET',
   // 返回的数据用于创建一个点赞记录
   data: {
    content_type: content_type,
    object_id: object_id,
    is_like: is_like,
   },
   cache: false,
   success: function (data) {
    console.log(data);
    if (data['status'] == 'SUCCESS'){
     // 更新点赞状态
     // 通过class找到对应的标签
     var record = $(obj.getElementsByClassName('glyphicon'))
     if (is_like){
      record.addClass('active')
     }
     else {
      record.removeClass('active')
     }
     // 更新点赞数量
     var like_num = $(obj.getElementsByClassName('like_num'))
     like_num.text('(' + data['like_num'] + ')')

    }
    else {
     // 以弹窗的形式显示错误信息
     alert(data['message'])
    }
   },
   error: function (xhr) {
    console.log(xhr)
   }
  });
  return false;
 };
</script>

最终效果图:

GitHub源码

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • django框架之cookie/session的使用示例(小结)

    一.http协议无状态问题 http协议没有提供多次请求之间的关联功能,协议的本意也并未考虑到多次请求之间的状态维持,每一次请求都被协议认为是一次性的.但在某些场景下,如一次登录多次访问,我们希望可以保存登录状态,协议并没有直接提供会话跟踪的支持,需要靠其他手段来帮助实现目标. 二.会话跟踪技术--cookie 1.对cookie的理解 cookie是一个key-value的数据结构(类似python字典),用于保存需要维护状态的数据,cookie与session最大的区别是cookie的数据保

  • Django框架教程之正则表达式URL误区详解

    前言 利用Django开发网站,可以设计出非常优美的url规则,如果url的匹配规则(包含正则表达式)组织得比较好,view的结构就会比较清晰,比较容易维护.但这其中可能会有一些误区,下面就来给大家总结下. 问题: 我学习的视频大概是2015年录的,里面用的Django版本比较老关于正则表达式URL这一块都是用的url("url(r'^admin/', admin.site.urls),")方法.而我自己练习的时候是下载的最新版本,而正则表达式URL用的确实path("pat

  • Django框架模板介绍

    定义:在Django框架中,模板是可以帮助开发者快速生成呈现给用户页面的工具 模板的设计方式实现了我们MVT中VT的解耦,VT有着N:M的关系,一个V可以调用任意T,一个T可以供任意V使用 模板处理分为两个过程 ① 加载 ② 渲染 模板主要有两个部分 ① HTML静态代码 ② 动态插入的代码段(挖坑,填坑) 模板中的动态代码段除了做基本的静态填充,还可以实现一些基本的运算,转换和逻辑. 模板中的变量: 视图传递给模板的数据,遵守标识符规则 语法{{ var }} 模板中的标签 语法 {% tag

  • Django框架多表查询实例分析

    本文实例讲述了Django框架多表查询.分享给大家供大家参考,具体如下: 多表查询是模型层的重要功能之一, Django提供了一套基于关联字段独特的解决方案. ForeignKey 来自Django官方文档的模型示例: from django.db import models class Blog(models.Model): name = models.CharField(max_length=100) tagline = models.TextField() class Author(mod

  • Django ORM框架的定时任务如何使用详解

    前言 大家在Django项目开发过程中,是不是也经常遇到这样的场景:需要实现一个定时任务,但又不想脱离Django环境独立运行,如:还需要使用Django的ORM框架操作Models类.日志框架.复用已有配置/方法等等. 大部分同学,初次接触时首先想到的就是使用第三方插件,如:django-celery,django-crontab等等,我也不例外,但实际使用过程,总有诸多不爽,要么感觉大材小用,要么功能支持不完整,要么使用很繁琐... 多次尝试摸索后,发现Django已经帮我们实现了该功能,使

  • Django contenttypes 框架详解(小结)

    一.什么是Django ContentTypes? Django ContentTypes是由Django框架提供的一个核心功能,它对当前项目中所有基于Django驱动的model提供了更高层次的抽象接口. 当然我们不是说的是http中的content-type!完全没有任何关系! 下面将一步一步解释Django ContentTypes在Django框架中做了什么,以及如何使用Django ContentTypes. 当然,如果对于ContentTypes有了初步了解而只是不了解它的应用场景,

  • Django框架的中的setting.py文件说明详解

    1.加载数据库,数据库的配置不能写死在seting.py文件中,下面的方式是读取另外一个文件,配置数据库: config = '' with open(os.path.join(BASE_DIR, 'config/config.json'), 'rt') as f: config = json.load(f) DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'szrqgl', 'USER': con

  • Python使用django框架实现多人在线匿名聊天的小程序

    最近看到好多设计类网站,都提供了多人在线匿名聊天的小功能,感觉很有意思,于是基于python的django框架自己写了一个,支持手动实时更名,最下方提供了完整的源码. 在线聊天地址(无需登录,开一个窗口,代表一个用户): http://zhaozhaoli.vicp.io/chatroom/happy/ 移动端聊天效果图: 网页版聊天效果图: 实现思路: 发送的消息通过ajax先写入数据库,通过ajax的循环请求,将写入数据库的消息显示到前端界面. 前端核心代码: <script> $(fun

  • Django框架模板注入操作示例【变量传递到模板】

    本文实例讲述了Django框架模板注入操作.分享给大家供大家参考,具体如下: 1.HTML模板如何解析变量? <h1>这是一个html页面</h1> <p>id:{{ user_id }}</p> <p>名字:{{ username }}</p> 其中:{{变量名}} 2.如何传递数据到HTML模板上? #coding:utf-8 from django.shortcuts import render,render_to_respon

  • Django框架实现的简单分页功能示例

    本文实例讲述了Django框架实现的简单分页功能.分享给大家供大家参考,具体如下: 前面一篇<Django开发的简易留言板>写了个简单的留言板,如果数据量太多的话在一页显示就不那么友好了,本文就是做一个分页显示. 代码在上一篇的基础上修改. 导入分页模块并修改views #只需修改index函数即可 from django.core.paginator import Paginator def index(request): messages = models.Message.objects.

随机推荐