计算来自另一个模型Django的点赞次数

时间:2019-11-12 21:23:09

标签: django django-rest-framework

实现一个用户喜欢宠物的相似模型。如果用户按下,isLike将为true,而isLike为false 型号

class pet(models.Model):
    name = models.CharField(max_length=50)

class likes(models.Model):
    petId = models.ForeignKey(
        "pet", on_delete=models.CASCADE, null=True)
    liker = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)
    isLike = models.BooleanField(default=False)

class countlikes(models.Model):
    petId = models.ForeignKey(
        "pet", on_delete=models.CASCADE, null=True)
    numOfLikes = models.PositiveSmallIntegerField(default=0)


序列化器

class PetSerializer( serializers.ModelSerializer):
    class Meta:
        model = pet
        fields = '__all__'


class LikesSerializer( serializers.ModelSerializer):
    class Meta:
        model = likes
        fields = '__all__'


class CountlikesSerializer(DynamicFieldsMixin, serializers.ModelSerializer):

    class Meta:
        model = countlikes
        fields = '__all__'

视图集

class PetViewSet(viewsets.ModelViewSet):
    queryset = pet.objects.all()
    permission_classes = [
        permissions.AllowAny
        # permissions.IsAuthenticated,
    ]
    serializer_class = PetSerializer

class LikesViewSet(viewsets.ModelViewSet):
    queryset = likes.objects.all()
    permission_classes = [
        permissions.AllowAny
        # permissions.IsAuthenticated,
    ]
    serializer_class = LikesSerializer

class CountlikesViewSet(viewsets.ModelViewSet):
    queryset = countlikes.objects.all()
    permission_classes = [
        permissions.AllowAny
        # permissions.IsAuthenticated,
    ]
    serializer_class = countlikesSerializer

我尝试了什么:两个获取请求以获取“喜欢”数,以及isLike是true还是false。如果用户喜欢,我会增加numOfLikes,如果用户不喜欢,我会减少,然后发出放置请求。

1 个答案:

答案 0 :(得分:1)

countlikes将在您的建模中引入数据重复,事实证明,保持数据同步比看起来要难。因此,我建议删除countlikes模型。尤其是因为它不是一个真实的实体:它是“ 纯制造”。

您可以在PetSerializer中添加两个额外的字段:

class PetSerializer(serializers.ModelSerializer):
    likes = serializers.IntegerField()
    dislikes = serializers.IntegerField()

    class Meta:
        model = pet
        fields = ('id', 'name', 'likes', 'dislikes')

然后在您的ModelViewSet中,传递一个带有注释的查询集:

from django.db.models import Count, Sum, Value
from django.db.models.functions import Coalesce

class PetViewSet(viewsets.ModelViewSet):
    queryset = pet.objects.annotate(
        likes=Coalesce(Sum('likes__isLike'), Value(0)),
        dislikes=Coalesce(Count('likes')-Sum('likes__isLike'), Value(0))
    )
    serializer_class = PetSerializer
  

注意:通常是Django模型,就像Python中的所有类在 PerlCase 中都有一个名称,而不是 snake_case 一样,因此它应该是:Pet而不是 pet

  

注意:通常,Django模型的名称为单数,因此使用Like而不是 likes

  

注意:由于Django,通常不会在_id字段中添加后缀ForeignKey   会自动添加带有后缀_id的“双胞胎”字段。因此它应该   是pet,而不是 petId