当前位置: 首页 > 面试题库 >

Django rest框架,在同一ModelViewSet中使用不同的序列化器

竺国兴
2023-03-14
问题内容

我想提供两个不同的序列化器,但仍然可以从以下所有功能中受益ModelViewSet

  • 当查看对象列表时,我希望每个对象都有一个重定向到其详细信息的url,并使用__unicode __目标模型来显示其他所有关系。
    例:
{
  "url": "http://127.0.0.1:8000/database/gruppi/2/",
  "nome": "universitari",
  "descrizione": "unitn!",
  "creatore": "emilio",
  "accesso": "CHI",
  "membri": [
    "emilio",
    "michele",
    "luisa",
    "ivan",
    "saverio"
  ]
}
  • 查看对象的详细信息时,我想使用默认值 HyperlinkedModelSerializer
    例:
{
  "url": "http://127.0.0.1:8000/database/gruppi/2/",
  "nome": "universitari",
  "descrizione": "unitn!",
  "creatore": "http://127.0.0.1:8000/database/utenti/3/",
  "accesso": "CHI",
  "membri": [
    "http://127.0.0.1:8000/database/utenti/3/",
    "http://127.0.0.1:8000/database/utenti/4/",
    "http://127.0.0.1:8000/database/utenti/5/",
    "http://127.0.0.1:8000/database/utenti/6/",
    "http://127.0.0.1:8000/database/utenti/7/"
  ]
}

我设法按照以下方式完成了所有这些工作:

serializers.py

# serializer to use when showing a list
class ListaGruppi(serializers.HyperlinkedModelSerializer):
    membri = serializers.RelatedField(many = True)
    creatore = serializers.RelatedField(many = False)

    class Meta:
        model = models.Gruppi

# serializer to use when showing the details
class DettaglioGruppi(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = models.Gruppi

views.py

class DualSerializerViewSet(viewsets.ModelViewSet):
    """
    ViewSet providing different serializers for list and detail views.

    Use list_serializer and detail_serializer to provide them
    """
    def list(self, *args, **kwargs):
        self.serializer_class = self.list_serializer
        return viewsets.ModelViewSet.list(self, *args, **kwargs)

    def retrieve(self, *args, **kwargs):
        self.serializer_class = self.detail_serializer
        return viewsets.ModelViewSet.retrieve(self, *args, **kwargs)

class GruppiViewSet(DualSerializerViewSet):
    model = models.Gruppi
    list_serializer = serializers.ListaGruppi
    detail_serializer = serializers.DettaglioGruppi

    # etc.

基本上,我会检测用户何时请求列表视图或详细视图,并进行更改serializer_class以满足我的需求。不过,我对这个代码并不真正满意,它看起来像是一个肮脏的骇客,而且最重要的是,如果两个用户同时请求列表和详细信息怎么办?

有没有更好的方法可以实现此目的,ModelViewSets还是我必须退后使用GenericAPIView

编辑:
这是使用自定义库的方法ModelViewSet

class MultiSerializerViewSet(viewsets.ModelViewSet):
    serializers = { 
        'default': None,
    }

    def get_serializer_class(self):
            return self.serializers.get(self.action,
                        self.serializers['default'])

class GruppiViewSet(MultiSerializerViewSet):
    model = models.Gruppi

    serializers = {
        'list':    serializers.ListaGruppi,
        'detail':  serializers.DettaglioGruppi,
        # etc.
    }

问题答案:

覆盖你的get_serializer_class方法。你的模型mixins中使用此方法来检索适当的Serializer类。

请注意,还有一种get_serializer方法可以返回正确的Serializer 的实例

class DualSerializerViewSet(viewsets.ModelViewSet):
    def get_serializer_class(self):
        if self.action == 'list':
            return serializers.ListaGruppi
        if self.action == 'retrieve':
            return serializers.DettaglioGruppi
        return serializers.Default # I dont' know what you want for create/destroy/update.    


 类似资料:
  • 我希望提供两种不同的序列化程序,同时又能够从的所有功能中获益: 当查看对象列表时,我希望每个对象都有一个重定向到其详细信息的url,并且使用目标模型的显示所有其他关系; 示例: 查看对象的详细信息时,我希望使用默认的 示例: 我设法通过以下方式使这一切如我所愿发挥作用: serializers.py views.py 基本上,我会检测用户何时请求列表视图或详细视图,并根据需要更改。我对这段代码并不

  • 我想在同一框架中使用2个面板。但是button不起作用了?我该怎么做?我想在一个面板上放几个按钮,另一个面板会做一些其他的事情。

  • 我的微服务需要通过HTTP与2个不同的服务进行通信。1个与snake_caseJSON有API契约,而另一个使用camelCase。如何配置WebFlux在一组功能endpoint上使用某个Jackson反序列化和序列化JSON,而在不同endpoint上使用另一个? WebFlux文档展示了如何连接另一个ObjectMapper,但这适用于我的API的所有endpoint。所以现在要么我所有的J

  • 我在序列化和反序列化同一JVM中的对象列表时遇到问题。确切地说,现在我的对象与对象具有相同的引用,它有以下规则: 现在在我的对象列表反序列化之后,在某个时候字母表引用不匹配。我用以下方法检查了一下: 得到了以下结果 现在看看VMId,既然它们是相同的,那么它不应该是相同的对象吗,就像上面的逻辑一样?谢谢你的帮助。

  • 问题内容: 在我试图基于y值为XY折线图/曲线的不同区域着色。我重写的 ,但我不知道它是如何处理 之间的线色小号,因为它只是让了(整数值)。 问题答案: 看起来线之间的着色的处理是在 线条颜色似乎基于先前的点 对您的修改使用渐变填充来混合线条颜色。 我已删除,因为我无权访问该类/方法。您可能需要修改以考虑 点之间的距离/渐变。

  • 我有一个使用ModelViewSet实现的模型。在这种情况下,GET and POST工作得很好。但是当我定义PUT时,我在rest客户机中得到以下响应: urls.py 有没有人可以建议我应该如何在这里实现update方法,以便下面的请求可以工作: