ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

实现点赞功能

2020-11-06 22:03:00  阅读:221  来源: 互联网

标签:功能 like 实现 object content models 点赞 type id


一、点赞功能设计

1、博客、评论、回复可点赞

2、可取消点赞

3、可看到点赞数

前端设计

                <div class="like" onclick="likeChange(this,'{% get_content_type blog %}',{{ blog.pk }})">
                    <span class="glyphicon glyphicon-thumbs-up {% get_likes_status blog %}"></span>
                    <span class="liked-num">{% get_like_count blog %}</span>
                    <span>喜欢</span>
                </div>
        function likeChange(obj, content_type, object_id){
            var is_like = obj.getElementsByClassName('active').length == 0
            $.ajax({
                url: "{% url 'like_change' %}",
                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'){
                        //更新点赞状态
                        var element = $(obj.getElementsByClassName('glyphicon'));
                        if(is_like){
                            element.addClass('active');
                        }else {
                            element.removeClass('active');
                        }
                        //更新点赞数量
                        var liked_num = $(obj.getElementsByClassName('liked-num'));
                        liked_num.text(data['liked_num']);
                    }else {
                        alert(data['message']);
                    }
                },
                error: function(xhr){
                    console.log(xhr)
                }
            });
        }

模型设计

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):
    # 将您的模型ForeignKey 设为ContentType 通过ContentType找到具体的模型
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()  # 记录对应模型的主键值 该字段可以存储您将要关联的模型中的主键值
    # 给您的模型一个 GenericForeignKey,并为其传递上述两个字段的名称。如果将这些字段分别命名
    # 为“ content_type”和“ object_id”,则可以忽略这些-这些是默认字段名称 GenericForeignKey。
    content_object = GenericForeignKey('content_type', 'object_id')

    liked_num = models.IntegerField(default=0)

#具体谁对哪个对象点赞,点赞记录
class LikeRecord(models.Model):
    #保存被点赞对象这个信息
    # 将您的模型ForeignKey 设为ContentType 通过ContentType找到具体的模型
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()  # 记录对应模型的主键值 该字段可以存储您将要关联的模型中的主键值
    # 给您的模型一个 GenericForeignKey,并为其传递上述两个字段的名称。如果将这些字段分别命名
    # 为“ content_type”和“ object_id”,则可以忽略这些-这些是默认字段名称 GenericForeignKey。
    content_object = GenericForeignKey('content_type', 'object_id')

    user = models.ForeignKey(User, on_delete=models.CASCADE)
    liked_time = models.DateTimeField(auto_now_add=True)

路由

from django.urls import path
from . import views

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

后端实现

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 ErrorResponse(code, message):
    data = {}
    data['status'] = 'ERROR'
    data['code'] = code
    data['message'] = message
    return JsonResponse(data)

def SuccessResponse(liked_num):
    data = {}
    data['status'] = 'SUCCESS'
    data['liked_num'] = liked_num
    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')

    # 处理数据
    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')

自定义模版标签,获取点赞数量,获取点赞状态用来实时显示状态,获取对象的content_type模型

from django import template
from django.contrib.contenttypes.models import ContentType
from ..models import LikeCount,LikeRecord

#用于注册,我们一会做的那些方法变成一个模版标签,可以给这个磨板试用,所以导入的是模版这个库
register = template.Library()

#写一个方法
#发这个方法注册一下
@register.simple_tag
def get_like_count(obj):
    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

#takes_context=True可以获取所在模版页面的模版变量
@register.simple_tag(takes_context=True)
def get_likes_status(context, obj):
    content_type = ContentType.objects.get_for_model(obj)
    user = context['user']
    if not user.is_authenticated:
        return ''
    if LikeRecord.objects.filter(content_type=content_type,object_id=obj.pk,user=context['user']).exists():
        return 'active'
    else:
        return ''

@register.simple_tag
def get_content_type(obj):
    content_type = ContentType.objects.get_for_model(obj)
    return content_type.model

 

 

 二、前后端开发建议

功能需求分析——模型设计——前端初步开发——后端实现——完善前端代码

标签:功能,like,实现,object,content,models,点赞,type,id
来源: https://www.cnblogs.com/lag1/p/13929614.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有