Ich möchte zwei verschiedene Serializer bereitstellen und dennoch von allen Möglichkeiten profitieren ModelViewSet
:
- Wenn ich eine Liste von Objekten ansehe, möchte ich, dass jedes Objekt eine URL hat, die zu seinen Details umleitet, und dass jede andere Beziehung unter Verwendung
__unicode __
des Zielmodells angezeigt wird.
Beispiel:
{
"url": "http://127.0.0.1:8000/database/gruppi/2/",
"nome": "universitari",
"descrizione": "unitn!",
"creatore": "emilio",
"accesso": "CHI",
"membri": [
"emilio",
"michele",
"luisa",
"ivan",
"saverio"
]
}
- Beim Anzeigen der Details eines Objekts möchte ich die Standardeinstellung verwenden
HyperlinkedModelSerializer
Beispiel:
{
"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/"
]
}
Ich habe es geschafft, all diese Arbeit so zu machen, wie ich es mir wünsche:
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.
Grundsätzlich erkenne ich, wann der Benutzer eine Listenansicht oder eine Detailansicht anfordert, und ändere serializer_class
sie entsprechend meinen Anforderungen. Ich bin jedoch nicht wirklich zufrieden mit diesem Code, er sieht aus wie ein schmutziger Hack und vor allem, was ist, wenn zwei Benutzer gleichzeitig eine Liste und ein Detail anfordern?
Gibt es einen besseren Weg, um dies mit zu erreichen, ModelViewSets
oder muss ich mit zurückgreifen GenericAPIView
?
BEARBEITEN:
So geht's mit einer benutzerdefinierten Basis 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.
}