• 实现点赞功能


    一、点赞功能设计

    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

     二、前后端开发建议

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

  • 相关阅读:
    React 高阶组件
    React Context(执行上下文)
    解决背景图片半透明(rgba)兼容性
    js基础复习---数组操作
    js基础复习---字符串操作
    escape()、encodeURI()、encodeURIComponent()区别详解(转)
    form data和request payload的区别(转)
    关于把时间搓转化为时间
    关于js 获取本地当前时间问题
    关于html 头部meta标签。
  • 原文地址:https://www.cnblogs.com/lag1/p/13929614.html
Copyright © 2020-2023  润新知