【问题标题】:Ordering on SerializerMethodField在 SerializerMethodField 上排序
【发布时间】:2016-07-03 15:42:40
【问题描述】:

我希望在 SerializerMethodField 上订购一个视频模型。需要进行排序的字段是 votes 和 likes,为此我使用了额外的 django 包,'votes' 和 'django-hitcount'。

#models.py
class Video(models.Model, HitCountMixin):
    '''
    Other properties
    '''
    votes = VotableManager()

#serializer.py
class VideoListSerializer(ModelSerializer):
    views = SerializerMethodField()
    likes = SerializerMethodField()
    class Meta:
        model = Video
        fields = [
            'title',
            'views',
            'likes'
        ]

    def get_likes(self, obj):
        return list(Video.objects.get(pk=obj.id).votes.likes()).count(True)

    def get_views(self, obj):
        return Video.objects.get(pk=obj.id).hit_count.hits

#API View for Most Viewed Videos
class VideoMostViewedAPIView(ListAPIView):
    serializer_class = VideoListSerializer
    queryset = Video.objects.all()
    filter_backends = [OrderingFilter]
  1. 我可以使用 API 端点成功订购:/videos/?ordering=title
  2. get_likes 和 get_views 函数工作正常。

我正在尝试在 VideoListSerializer 上同时使用“views”和“likes”SerializerMethodField 进行订购,例如 /videos/most-viewed/?ordering='-likes',但它似乎不起作用。有什么办法可以按那个字段排序吗?

我已经看过这个问题:Django Rest Framework Ordering on a SerializerMethodField 但不知何故,它并不能帮助我解决我的问题。

我也尝试过使用带有 annotate() 方法的 Count 进行聚合,但我也可以使用字段值,例如 'votes' 而不是像 votes.likes() 这样的事情,这显然是不可能的。


编辑 1

我使用外部 django 包来查看和喜欢/不喜欢。所以, votes.likes() 实际上返回一个包含真假的列表。

例如,假设我有一个 API 调用,

/api/votes/up/?model=video&id=15&vote=true

那么请求用户将投票给 id=15 的视频模型对象。同样在做

/api/votes/likes/?model=video&id=15

将返回 id=15 的视频模型对象的好恶,与在我的序列化程序中使用 votes.likes() 相同。

另外,因为我只想要喜欢,所以我会 list(instance.votes.likes()).count(True) 只计算正确的选票(即赞成票)。

同样,为了计算视图,我使用模型的 hit_count 属性,该属性不是由我定义的,但可以通过添加 HitCountMixin 获得,然后我从中返回命中。

【问题讨论】:

  • 我认为你需要更具体地了解你的 votes.likes() 方法看起来像什么是 hit_count.hits,你的模型是如何构造的,所以我们可以帮助你使用 annotate 方法,因为您最好的选择是注释查询集。 (而且我认为这也不应该那么难)
  • @Nirri 我已经更新了在我的模型中使用投票和视图的详细信息。我仍然不知道如何注释它。

标签: django django-rest-framework


【解决方案1】:

好的,为了让您了解如何开始,您必须更深入地研究您正在使用的那些包。

据我所知,django-hitcount 有一个 HitCount 模型,其中 content_object 作为视频的外键。它有一个名为 hits 的 PositiveIntegerField,其中包含对象的命中数。因为它是一个外键,你可能必须通过 Max 或类似的东西来运行它。 有关更多信息,请参阅他们的 models.py here

对于 django-vote,您的对象收到的每张选票都有一个 Vote 类的实例。它还通过 GenericForeignKey 关系连接到您的 Video 对象。所以你只是数一下就很好了。 有关更多信息,请参阅他们的 models.py here

告诉我进展如何。

【讨论】:

    猜你喜欢
    • 2015-07-14
    • 2014-12-31
    • 2020-12-09
    • 2020-10-20
    • 2019-05-12
    • 2019-01-07
    • 2016-07-21
    • 2022-06-14
    • 1970-01-01
    相关资源
    最近更新 更多