【Django2.0学习笔记】28.用所学知识实现点赞功能

28、用所学知识实现点赞功能

1、点赞功能设计

  • 1、博客和评论、回复可点赞
  • 2、可取消点赞
  • 3、可看到点赞总数
    在这里插入图片描述

因为点赞是一个独立的功能模板,它可以加到任意位置,所以最好是新创建一个点赞app,
python manage.py startapp likes,app创建完成后,到里面的models.py进行创建:

# # C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\likes\models.py
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


# 点赞总数
class LikeCount(models.Model):
	# 这三个是描述ContentType的
	content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
	object_id = models.PositiveIntegerField()
	content_object = GenericForeignKey('content_type', 'object_id')

	# 已点赞数量
	liked_num = models.IntegerField(default=0)

# 具体的点赞记录
class LikeRecord(models.Model):
	# 对 哪个对象 进行点赞
	content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
	object_id = models.PositiveIntegerField()
	content_object = GenericForeignKey('content_type', 'object_id')

	# 谁点赞
	user = models.ForeignKey(User, on_delete=models.CASCADE)
	# 点赞时间
	liked_time = models.DateTimeField(auto_now_add=True)

那么这个基础的模型就创建完毕,我们再注册下这个应用,在settings.py里面注册likes这个app:
在这里插入图片描述

然后迁移数据库
在这里插入图片描述

下一步,首先我们看一下前端页面,具体博客页面blog_detail.html
在这里插入图片描述
启动服务,刷新页面
在这里插入图片描述
调整css样式:
在这里插入图片描述
在这里插入图片描述

那么我们要先实现点赞完之后有变颜色的效果,这就涉及到一个onclick点击事件,要让它实现:如果没有点赞的状态,会变成点赞的状态,并且点赞数加1;如果是点赞的状态下,就要有取消点赞,并且点赞数减1。这一系列操作比较多,我们可以写成一个function,然后在这里调用就行
在这里插入图片描述
这里,我们前端页面暂时写到这个地方,等后端代码完成后再写完善前端页面

新建一个url路由,在likes下新建urls.py,写入如下代码:

# # C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\likes\urls.py
from django.urls import path
from . import views

urlpatterns = [
	path('like_change', views.like_change, name='like_change')
]

另外,这个是加的应用的路由,我们还需要加到总的路由里面,修改mysite/urls.py如下:
在这里插入图片描述
路由配置完之后,前端页面就可以写入url了,提交数据到这个链接里面
在这里插入图片描述
另外,回头看一下models,models添加记录,需要提交content_type、object_id这两个数据,确定所点赞的对象(user可以通过request得到,我们这里就不需要提交这个数据),那么我们就可以继续完善html里面的data:
在这里插入图片描述
在这里插入图片描述
至此,前端页面又告一段落了,因为我们提交数据到后台这里没有任何的处理方法进行处理,只是提交了数据。那么就需要我们在后台处理方法views.py写入如下代码:

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


def SuccessResponse(liked_num):
	data = {}
	data['status'] = "SUCCESS"
	data['liked_num'] = liked_num
	return JsonResponse(data)

def ErrorResponse(code, message):
	data = {}
	data['status'] = 'ERROR'
	data['code'] = code
	data['message'] = message
	return JsonResponse(data)

def like_change(request):
	# 获取数据
	user = request.user
	# 判断用户是否登录
	if not user.is_authenticated:
		return ErrorResponse(400, 'you were not login')

	content_type =request.GET.get('content_type')
	object_id = int(request.GET.get('object_id'))
	try:
		content_type = ContentType.objects.get(model=content_type)
		model_class = content_type.model_class()
		model_obj = model_class.objects.get(pk=object_id)
	except ObjectDoesNotExist:
		return ErrorResponse(401, 'object not exist')

	# is_like = request.GET.get('is_like')

	# 处理数据
	if request.GET.get('is_like') == 'true':
		# 要点赞
		# 获取或者创建记录
		like_record, created = LikeRecord.objects.get_or_create(content_type=content_type, object_id=object_id, user=user)
		if created:
			# 未点赞过,进行点赞
			like_count, created = LikeCount.objects.get_or_create(content_type=content_type, object_id=object_id)
			like_count.liked_num += 1
			like_count.save()
			return SuccessResponse(like_count.liked_num)
		else:
			# 已点赞过,不能重复点赞
			return ErrorResponse(402, 'you were liked')
	else:
		# 要取消点赞
		if LikeRecord.objects.filter(content_type=content_type, object_id=object_id, user=user).exists():
			# 有点赞过,取消点赞
			like_record = LikeRecord.objects.get(content_type=content_type, object_id=object_id, user=user)
			like_record.delete()
			# 点赞总数减1
			like_count, created = LikeCount.objects.get_or_create(content_type=content_type, object_id=object_id)
			if not created:
				like_count.liked_num -= 1
				like_count.save()
				return SuccessResponse(like_count.liked_num)
			else:
				return ErrorResponse(404, 'data error')
		else:
			# 没有点赞过,不能取消
			return ErrorResponse(403, 'you were not liked')

完成后,我们刷新页面。
如果没有登录,我们点击“点赞”,可以看到
在这里插入图片描述

我们登陆后,点击
在这里插入图片描述
我们可以先把点赞总数显示出来,我们可以考虑用之前讲到过的自定义模板标签,在likes下新建templatetags文件夹,在该文件夹下面加一个_init__.py文件,然后新建likes_tags.py:
在这里插入图片描述

# # C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\likes\templatetags\likes_tags.py
from django import template
from django.contrib.contenttypes.models import ContentType
from ..models import LikeCount

register= template.Library()	# 用于注册

@register.simple_tag  # 将这个方法注册为simple_tag
def get_like_count(obj): # 传入obj这个对象,这个对象可以是任意类型。这里我们现在使用的是blog类型
	content_type = ContentType.objects.get_for_model(obj)
	like_count, created = LikeCount.objects.get_or_create(content_type=content_type, object_id=obj.pk)
	return like_count.liked_num

重启服务没有问题

然后我们在前端页面使用它。修改blog_detail.html如下:
在这里插入图片描述
刷新页面,可以看到刚刚点赞过的地方 点赞数量加了1
在这里插入图片描述
同样的,在外面博客列表页面,我们也可以加上显示点赞数量,修改blog_list.html
在这里插入图片描述
刷新页面
在这里插入图片描述

回到之前的位置,我们点赞过之后,我们要在blog_detail页面对应位置动态判断加上active。这里我们是可以用后台处理方法做一个变量将它传进来,但这个处理方法是在博客里边 也就是blog应用里,如果我们在这里面写,会变得更加复杂。既然这里我们已经加了自定义模板标签, 那么我们可以考虑通过这个模板标签返回到底需不需要加active,新加一个自定义模板标签,修改likes_tags.py如下:
在这里插入图片描述

然后在blog_detail.html进行使用
在这里插入图片描述
刷新页面
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

我们继续完善前端页面blog_detail.html
在这里插入图片描述
在这里插入图片描述

完善二:对评论也有点赞功能
新增一个模板标签,获取对象的ContentType类型,修改likes_tags.py如下:
在这里插入图片描述
再修改blog_detail.html如下(复制点赞这块儿的html代码分别到评论和回复评论处,并修改对应的传给likes_tags.py新建的模板标签的obj参数 即对应的ContentType类型,因为之前的点赞这块html代码这里,给likeChange传入ContentType参数是直接写的‘blog’):
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
刷新页面,对评论和回复点赞测试一下:
在这里插入图片描述

2、前后端开发建议

功能需求分析 --> 模型设计 --> 前端初步开发 --> 后端实现 --> 完善前端代码
在这里插入图片描述

3、运用到所学什么知识

  • Django基础(models、views、urls、…)
  • ContentType
  • ajax
  • 自定义模板标签
    在这里插入图片描述
  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值