我想提供两个不同的序列化器,但仍然能够从以下所有功能中受益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以满足我的需求。我对这段代码并不真正满意,它看起来像是一个肮脏的hack,最重要的是,如果两个用户同时请求一个列表和一个细节怎么办?  
有没有更好的方法可以实现此目的,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.
    }