我是Django的REST框架中的新手,我有一个练习。我想从两种Django型号创建自定义JSON输出。我已经创建了两个序列化视图。输出JSON应该是:
{
"movie_id": 2,
"total_comments": 4,
"rank": 1
},
{
"movie_id": 3,
"total_comments": 2,
"rank": 2
},
{
"movie_id": 4,
"total_comments": 2,
"rank": 2
}
,get/top URL应该:
应根据在指定日期范围内添加到电影中添加的许多注释(如示例(中返回数据库排名中已经存在的顶级电影。响应应包括电影的ID,等级的位置和评论总数(在指定的日期范围内(。
具有相同数量评论的电影在排名中应具有相同的位置。
应要求指定应生成统计信息的日期范围。
我有两个序列化:
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model= Comment
fields=('movie','user','timestamp','content','approved')
class MovieSerializer(DynamicFieldsModelSerializer,serializers.HyperlinkedModelSerializer):
comments=CommentSerializer(many=True)
comments=None
class Meta:
model = Movie
fields = ('id','name','description','year','released','comments','rating')
这是评论模型:
class Comment(models.Model):
movie = models.ForeignKey(Movie, on_delete=models.DO_NOTHING,related_name='comments',blank=True,null=True)
content = models.TextField()
timestamp = models.DateTimeField(default=timezone.now)
user=models.CharField(max_length=250)
我试图通过这个技巧自己做到这一点:
class MovieViewSet(viewsets.ModelViewSet):
queryset = Movie.objects.all()
serializer_class = MovieSerializer
class CommentViewSet(viewsets.ModelViewSet):
queryset = Comment.objects.all()
serializer_class = CommentSerializer
class TopViewSet(viewsets.ModelViewSet):
serializer_class = MovieSerializer
#queryset = Movie.objects.annotate(comment_count=(Count('comments'))).order_by("-comment_count","-rating")
queryset = Movie.objects.all().annotate(comment_count=(Count('comments'))).order_by("-comment_count")
,但我不知道如何创建自定义的JSON输出
如果有人在最后一点也可以帮助我,即日期,我会很感激。
我想你可以这样做:
# serializer
class MovieSerializer(HyperlinkedModelSerializer):
comments = CommentSerializer(many=True)
comments_count = serializer.IntegerField()
rank = serializer.IntegerField()
class Meta:
model = Movie
fields = ('id','name','description','year','released','comments','rating', 'comments_count', 'rank')
# Viewset
from django.db.models import Sum, F
from django.db.models.expressions import Window
from django.db.models.functions import Rank
class TopViewSet(viewsets.ModelViewSet):
serializer_class = MovieSerializer
queryset = Movie.objects.all()
def get_queryset(self, *args, **kwargs):
from_date = self.request.query_params.get('from_date')
to_date = self.request.query_params.get('to_date')
movies = super(ToViewSet, self).get_queryset()
if from_date and to_date:
movies = movies.filter(release__range=[from_date, to_date])
return movies.annotate(comment_count=Count('comments'), rank=Window(expression=Rank(), order_by=F('comments').desc()),)
说明:
在get_queryset()
方法中,我使用 self.request.query_params.get(...)
。这用于获取 URL Querystring
。因此,当您调用/your_url/?from_date=2018-01-01&to_date=2019-01-31
时,它将在给定的日期范围之间过滤queryset。
另外,我已经使用了django模型的 Window Function
来注释对象的等级。
最后,在序列化器中,我在Serializer
中添加了2个额外的字段。它将从QuerySet捕获带注释的值并显示为输出。
我认为您应该在视图中重写获取方法:
from rest_framework.response import Response
from rest_framework import status
class MovieViewSet(viewsets.ModelViewSet):
queryset = Movie.objects.all()
serializer_class = MovieSerializer
def get(self):
""" do some thing"""
output = {{
"movie_id": 2,
"total_comments": 4,
"rank": 1
},
{
"movie_id": 3,
"total_comments": 2,
"rank": 2
},
{
"movie_id": 4,
"total_comments": 2,
"rank": 2
}
}
return Response(output, status=status.HTTP_200_OK)
有关更多详细信息,请阅读DRF文档:https://www.django-rest-framework.org/api-guide/generic-views/#generic-views