【问题标题】:Sort DRF serializer output of nested Serializer field by child's field按子字段对嵌套序列化器字段的 DRF 序列化器输出进行排序
【发布时间】:2017-06-07 16:29:00
【问题描述】:

我有两个序列化程序,其中一个以many=True 关系引用另一个。

class AttributeInParentSerializer(ModelSerializer):
    masterdata_type = CharField(max_length=256, source='masterdata_type_id')

    class Meta:
        model = Attribute
        fields = ('uuid', 'masterdata_type')

class ArticleInArticleSetSerializer(ModelSerializer):
    attributes = AttributeInParentSerializer(many=True)

    class Meta:
        model = Article
        fields = ('uuid', 'attributes')    

文章中属性的顺序并不总是相同的,但我想以相同的顺序输出它们,所以在这种情况下对字段masterdata_type进行排序。我怎样才能做到这一点?请注意,如果可能,我不想更改序列化程序的任何客户端,当然也不想更改任何模型。

【问题讨论】:

    标签: django sorting django-rest-framework serialization


    【解决方案1】:

    旧线程,但由于它仍在 Google 上弹出,我也想分享我的答案。尝试覆盖Serializer.to_representation 方法。现在您基本上可以做任何您想做的事情,包括自定义响应的排序。在你的情况下:

    class ArticleInArticleSetSerializer(ModelSerializer):
        attributes = AttributeInParentSerializer(many=True)
    
        class Meta:
            model = Article
            fields = ('uuid', 'attributes')
    
        def to_representation(self, instance):
            response = super().to_representation(instance)
            response["attributes"] = sorted(response["attributes"], key=lambda x: x["masterdata_type"])
            return response
    

    【讨论】:

    • 我在相同的场景中尝试过这个并且它的工作。应标记为已接受,因为它可以根据问题提供解决方案。
    【解决方案2】:

    您可以通过为 ArticleInArticleSetSerializer 编写视图集来设置 ArticleInArticleSetSerializer 上的属性顺序。

    class ArticleInArticleSetViewSet(viewsets.ModelViewSet):
        serializer_class = ArticleInArticleSetSerializer
        queryset = Article.objects.all().order_by('-attributes_id')
    

    或者你可以写一个函数来列出。

    def list(self, request):
        self.queryset = self.get_queryset().order_by('-id')
        return super(yourViewSet, self).list(self, request)
    

    此代码仅供参考

    【讨论】:

    • 感谢您的回答!如果将在视图中使用序列化器,则此答案是一种解决方案。但是我在另一个序列化器中使用序列化器,我想为序列化器的所有客户端解决这个问题。所以说实话,我看不出这个答案会有什么帮助。
    【解决方案3】:

    您不能在ArticleInArticleSetSerializer 上设置排序,但您可以在AttributeInParentSerializer 上设置attributes 的排序。这是因为您只能在使用序列化程序而不是在定义序列化程序时设置排序。

    当传入查询集或数据时,您也许可以在 __init__ 方法中设置它,但是您正在对传入的内容做出假设。我可能最终会在 @ 的消费者中指定它987654325@ 以避免将来在将列表传递给序列化程序时出现任何问题。

    【讨论】:

    • 您是说:您可以在ArticleInArticleSetSerializer 上设置attributes 的排序。这实际上是我的确切问题:我该怎么做?
    【解决方案4】:

    您可以像这样在序列化程序中使用order_by

    class AttributeInParentSerializer(ModelSerializer):
        masterdata_type = CharField(max_length=256, source='masterdata_type_id')
    
        class Meta:
            model = Attribute
            fields = ('uuid', 'masterdata_type')
            order_by = (('masterdata_type',))
    

    希望对你有帮助!

    更新:

    看来我错了。从文档中找不到它,它似乎不起作用。现在,我不认为序列化程序是进行排序的地方。最好的方法是在模型中或视图中。

    【讨论】:

    • 您能否链接到在序列化程序的元类上显示 order_by 属性的文档?我找不到它们,也找不到任何命令来处理示例 sn-p。
    • @schillingt 抱歉,看来我弄错了。请看我的更新
    • 好的,很酷。我们在同一页上。感谢您的检查。
    猜你喜欢
    • 2021-03-19
    • 2021-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-04
    相关资源
    最近更新 更多