【问题标题】:Django REST Framework: list of different serizalized objects?Django REST Framework:不同序列化对象的列表?
【发布时间】:2014-02-09 16:49:51
【问题描述】:

我有三种不同类型的对象:RawArticleRawPatentRawGrant

我有很棒的序列化器,它的基类是serializers.ModelSerializer

如果我检索到 RawArticle 的查询集,我可以使用 many=True 将其直接传递给序列化程序,并且输出是标称的:

[{"save_link": "...", "published": "2014-01-18T20:39:54.086Z", }, {"save_link": "...", "published": "..."}, ...]

此响应由以下代码生成:

return Response(RawArticleSerializer(articles, many=True).data)

现在我有了三个不同的对象,我想像上面一样将它们链接起来,但要使用它们各自的对象。

到目前为止,我一直没有成功。我最初的想法是简单地创建一个序列化对象的列表并返回它(当然是序列化的),如下所示:

    all_latest = user_latest(request)['latest_articles']

    available_serializers = {RawArticle: RawArticleSerializer, RawGrant: RawGrantSerializer, RawPatent: RawPatentSerializer}
    serialized = []
    for article in all_latest:
        serialized.append((available_serializers[type(article)](article, many=False)).data)

    return Response(str(serialized))

上面的代码不返回 JSON 并且日期时间没有转换为实际的日期和时间作为字符串。

我最近的尝试是使用 json.dumps 和 simplejson 并且都提出了 TypeError 说:

日期时间对象不可序列化。

任何提示将不胜感激。

【问题讨论】:

    标签: django json serialization django-rest-framework


    【解决方案1】:

    就个人而言,为了处理序列化程序,我在我的模型中创建了一个serialize 方法。该方法依次调用相应的代码来序列化数据。

    在这种情况下,代码如下所示:

    class RawArticle(models.Model):
       def serialize(self):
           return RawArticleSerializer(self, many=False).data
    

    然后,在您的主代码中:

    from rest_framework.renderers import JSONRenderer
    
    all_latest = user_latest(request)['latest_articles']
    
    serialized = [article.serialize() for article in all_latest]
    return Response(JSONRenderer().render(serialized))
    

    即使对象不是模型,这种方法应该仍然有效。

    【讨论】:

    • 其实这会返回一个字符串。在 .data 之后返回一个列表就可以了,正如我将在下面的回答中解释的那样。
    • 这里缺乏良好的实践:将序列化登录与业务实体分开。我建议的方法只是:serialized = [RawArticleSerializer(article, many=False).data for article in all_latest] 并从 RawArticle 类中删除 serialize() 方法
    【解决方案2】:

    Sunny 的答案将 JSON 作为字符串返回(用双引号括起来)。为了避免这种情况,返回列表可以满足我的需要:

        serialized = []
        AVAILABLE_SERIALIZERS = {RawArticle: RawArticleSerializer, RawGrant: RawGrantSerializer, RawPatent: RawPatentSerializer}
        for article in articles:
            serialized.append((AVAILABLE_SERIALIZERS[type(article)](article, many=False)).data)
    
        return Response(serialized)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-12
      • 2015-03-15
      • 2016-10-22
      • 2013-05-23
      • 2020-07-17
      • 1970-01-01
      • 2016-07-21
      • 2021-11-30
      相关资源
      最近更新 更多