ฉันต้องการมอบ serializers ที่แตกต่างกันสองแบบและยังสามารถได้รับประโยชน์จากสิ่งอำนวยความสะดวกทั้งหมดของ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.
}