【问题标题】:Sorting the django objects based on SerializerMethodField基于 SerializerMethodField 对 django 对象进行排序
【发布时间】:2020-10-20 17:48:07
【问题描述】:

我正在尝试根据两个用户之间最后一条消息的时间戳来排序用户配置文件。

我正在使用 SerializerMethodField 来获取最后一条消息的时间戳。

有什么方法可以对数据进行排序吗?

class UserProfileSerializer(serializers.ModelSerializer):
    lastmessage = serializers.SerializerMethodField()
    class Meta:
        model = User
        fields = ['id','lastmessage']
    def get_lastmessage(self,obj): 
        k = self.context.get('view').kwargs['sid']
        data =( Message.objects.filter(receiver=obj.id,sender=k) | Message.objects.filter(sender=obj.id,receiver=k)).order_by('-timestamp').values('message','timestamp')
        if len(data) == 0:
            return ""
        else:
            data = data.first()
            data["timestamp"] = str(data["timestamp"])
        return str(data)

我的看法:

   class UserChatViewSet(viewsets.ModelViewSet): 
       queryset = User.objects.all() 
       serializer_class = UserProfileSerializer

现在我的观点回归了:

[{
    "id": 4,
    "lastmessage": "{'message': 'random', 'timestamp': '2020-06-14 23:49:33.077749+00:00'}"
},
{
    "id": 5,
    "lastmessage": ""
},
{
    "id": 6,
    "lastmessage": "{'message': 'sample', 'timestamp': '2020-06-14 11:53:03.880833+00:00'}"
},
{
    "id": 7,
    "lastmessage": ""
}]

但我希望它根据最后一条消息的时间戳进行排序

【问题讨论】:

  • 你能发表你的看法吗?get_queryset 方法
  • class UserChatViewSet(viewsets.ModelViewSet): queryset = User.objects.all() serializer_class = UserProfileSerializer

标签: django django-rest-framework django-views django-serializer django-jsonfield


【解决方案1】:

你的响应顺序应该在视图中处理。

  from django.db.models import Subquery, OuterRef
 lm = Message.objects.filter(sender=OuterRef("id"), receiver=self.kwargs['sid']).order_by('-timestamp')   
    data = User.objects.all().annotate(
        lastmessage=Subquery(
                    lm.values('timestamp')[:1]
                )
    ).order_by('-lastmessage__timestamp')

【讨论】:

  • 返回:“子查询”对象没有属性“order_by”
  • 现在给出:这个查询集包含对外部查询的引用,并且只能在子查询中使用。
  • 同样的错误。我认为应该是 .order_by('-lastmessage__timestamp') 而不是 order_by('-last_message__timestamp')
  • 已更正,但错误不同@saibhaskar
【解决方案2】:

您可以覆盖list 以实现此目的:

def list(self, request, *args, **kwargs):
    response = super().list(request, args, kwargs)
    # sort response.data['results']
    return response

另外,lastmessage 可以是 dict 而不是 str,因此更易于使用。

【讨论】:

  • 这会起作用,但是正如您在我的输出中看到的,最后一条消息有一些空值,这会导致排序错误
猜你喜欢
  • 2015-12-13
  • 2017-09-17
  • 1970-01-01
  • 1970-01-01
  • 2019-04-10
  • 2011-05-03
  • 2014-04-01
  • 2018-04-21
  • 2021-03-19
相关资源
最近更新 更多