aww*_*ter 14 django django-rest-framework
我有一个论坛主题模型,我想在计算的SerializerMethodField上订购,例如vote_count.以下是一个非常简化的Model,Serializer和ViewSet来显示问题:
# models.py
class Topic(models.Model):
"""
An individual discussion post in the forum
"""
title = models.CharField(max_length=60)
def vote_count(self):
"""
count the votes for the object
"""
return TopicVote.objects.filter(topic=self).count()
# serializers.py
class TopicSerializer(serializers.ModelSerializer):
vote_count = serializers.SerializerMethodField()
def get_vote_count(self, obj):
return obj.vote_count()
class Meta:
model = Topic
# views.py
class TopicViewSet(TopicMixin, viewsets.ModelViewSet):
queryset = Topic.objects.all()
serializer_class = TopicSerializer
Run Code Online (Sandbox Code Playgroud)
这是有效的:
/topics?ordering=title我试图通过TopicSerializer上的MethodField订购,/topics?ordering=-vote_count但是看起来似乎不支持.我有什么方法可以通过那个领域订购吗?
我简化的JSON响应如下所示:
{
"id": 1,
"title": "first post",
"voteCount": 1
},
{
"id": 2,
"title": "second post",
"voteCount": 8
},
{
"id": 3,
"title": "third post",
"voteCount": 4
}
Run Code Online (Sandbox Code Playgroud)
我正在使用Ember来使用我的API并且解析器将它转换为camelCase.我也尝试过order = voteCount,但这不起作用(它不应该)
Kev*_*own 33
使用默认值OrderingFilter是不可能的,因为排序是在数据库端实现的.这是出于效率的原因,因为手动对结果进行排序可能会非常慢,并且意味着违反标准QuerySet.通过将所有内容保持为一个QuerySet,您可以从Django REST框架(通常需要a QuerySet)和内置分页(没有一个可能很慢)中提供的内置过滤中受益.
现在,在这些情况下,您有两种选择:弄清楚如何在数据库端检索您的值,或尝试最小化您将不得不采取的性能损失.由于后一种选择是特定于实现的,我现在要跳过它.
在这种情况下,您可以使用Django提供的Count功能在数据库端进行计数.这是作为聚合API的一部分提供的,其工作方式与SQL COUNT函数类似.您可以Count通过修改queryset视图来进行等效调用
queryset = Topic.objects.annotate(vote_count=Count('topicvote_set'))
Run Code Online (Sandbox Code Playgroud)
更换topicvote_set与你related_name的领域(你有一组吧?).这将允许您根据投票数量排序结果,甚至可以进行过滤(如果您愿意),因为它在查询本身中可用.
这需要对序列化程序稍作更改,因此它会从vote_count对象上可用的新属性中获取.
class TopicSerializer(serializers.ModelSerializer):
vote_count = serializers.IntegerField(read_only=True)
class Meta:
model = Topic
Run Code Online (Sandbox Code Playgroud)
这将覆盖您现有的vote_count方法,因此您可能希望重命名注释时使用的变量(如果您不能替换旧方法).
此外,您可以将方法名称作为sourceDjango REST框架字段传递,它将自动调用它.从技术上讲,你当前的序列化器可能就是这样
class TopicSerializer(serializers.ModelSerializer):
vote_count = serializers.IntegerField(read_only=True)
class Meta:
model = Topic
Run Code Online (Sandbox Code Playgroud)
而且它的工作正是像它目前做.请注意,read_only在这种情况下需要,因为方法与属性不同,因此无法设置该值.
| 归档时间: |
|
| 查看次数: |
7184 次 |
| 最近记录: |