我想提供两个不同的序列化器,但仍然可以从以下所有功能中受益ModelViewSet:
ModelViewSet
__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以满足我的需求。不过,我对这个代码并不真正满意,它看起来像是一个肮脏的骇客,而且最重要的是,如果两个用户同时请求列表和详细信息怎么办?
serializer_class
有没有更好的方法可以实现此目的,ModelViewSets还是我必须退后使用GenericAPIView?
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_class
请注意,还有一种get_serializer方法可以返回正确的Serializer 的实例
get_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.