【问题标题】:Order data by non-database field按非数据库字段排序数据
【发布时间】:2016-08-30 17:40:22
【问题描述】:

我正在使用 Django rest 框架,这是我用于社交应用的 serializers.py:

class SocialPostSerializer(serializers.ModelSerializer):

    likes = serializers.SerializerMethodField() # define field

    class Meta:
        model = SocialPost

    def get_likes(self, obj):
        post_id = obj.id
        #I get post_like from django-redis
        post_like = get_redis_connection("default")
        likes = post_like.get("post"+":"+str(post_id))
        if likes == None:
            return 0
        else:
            likes = likes.decode('utf-8')
            return likes

通过上面的代码,我从 API 中得到了我需要的东西。

由于我的数据库中不存在 'likes'(此处为 Mysql),我无法使用 order_by('likes') 使用 django ORM 对数据进行排序

我在这里遵循ListCreateAPIView 的文档,它引导我覆盖 list():(我之前覆盖了 create() 和 get_queryset())

from operator import itemgetter

class PostList(generics.ListCreateAPIView):
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
    queryset = Post.objects.all()
    serializer_class = PostAllSerializer


    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        #problem here
        serializer.data = sorted(serializer.data, key=itemgetter(serializer.data['likes']))
        return Response(serializer.data)

    def create(self, request, *args, **kwargs):
        act_id = request.data.get('act')
        act = Act.objects.get(pk=act_id)
        if act.act_type == 0:
            if request.user != act.user:
                return Response(status=403)
        return super().create(request, args, kwargs)

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)

    def get_queryset(self):
        queryset = Post.objects.all().order_by('-post_create_time')
        act_id = self.request.query_params.get('act_id', None)
        post_author = self.request.query_params.get('post_author', None)
        if act_id is not None:
            queryset = queryset.filter(act=act_id)
        if post_author is not None:
            queryset = queryset.filter(user__user_name=post_author)
        return queryset

什么都没有发生,即使我取消注释也是连线的

return Response(serializer.data)

还是什么都没发生,是哪一部分出错了?

另一个问题是,当我使用 django FBV 时,我想添加一些额外的数据,例如“问题”:

def results(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/results.html', {'question': 'some data I wanna add'})

是否可以在 serializer.data 中添加数据?例如,我想显示来自哪个用户请求此 api 的 user_id:

def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        user_id = request.user.id #how can I add the user_id into response data?
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

我在这里查看文档Including extra context

serializer = AccountSerializer(account, context={'request': request})

我不太明白如何在其中添加数据。

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    “由于我的数据库(这里是Mysql)中不存在'likes',所以我不能使用order_by('likes') 对django ORM 中的数据进行排序”

    您将无法使用 django ORM 对结果进行排序,因为 likes 字段不是您的数据库表的一部分。唯一的方法是对您在视图中获得的 serializer.data 进行排序。在您的情况下,serializer.data 将是一个字典列表,您可以对列表使用排序命令并使用 lambda 对喜欢进行排序。

    这里要注意的一件事是,由于您将通过将数据加载到内存中来进行排序,因此请确保您不会加载大量数据。检查内存利用率。

    “另一个问题是,当我使用 django FBV 时,我想添加一些额外的数据,例如‘问题’”

    我不明白这里需要什么。

    【讨论】:

    • 我尝试覆盖 list(),但没有任何反应。我已针对第二个问题更新了我的帖子。
    • 谢谢,我只是想念'if page is not None:' 这一行
    猜你喜欢
    • 1970-01-01
    • 2023-01-03
    • 1970-01-01
    • 1970-01-01
    • 2018-04-20
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    相关资源
    最近更新 更多