Aktualisiert am 05. Juli 2020
Dieser Beitrag erhält mehr Aufmerksamkeit und zeigt an, dass mehr Menschen eine ähnliche Situation haben. Deshalb habe ich beschlossen, einen generischen Weg hinzuzufügen , um dieses Problem zu lösen. Diese generische Methode eignet sich am besten für Sie, wenn Sie mehr Serializer haben, die in dieses Format geändert werden müssen.
Da DRF diese Funktionalität nicht sofort bereitstellt, müssen wir zuerst ein Serializer-Feld erstellen .
from rest_framework import serializers
class RelatedFieldAlternative(serializers.PrimaryKeyRelatedField):
def __init__(self, **kwargs):
self.serializer = kwargs.pop('serializer', None)
if self.serializer is not None and not issubclass(self.serializer, serializers.Serializer):
raise TypeError('"serializer" is not a valid serializer class')
super().__init__(**kwargs)
def use_pk_only_optimization(self):
return False if self.serializer else True
def to_representation(self, instance):
if self.serializer:
return self.serializer(instance, context=self.context).data
return super().to_representation(instance)
Ich bin nicht sehr beeindruckt von diesem Klassennamen RelatedFieldAlternative, Sie können alles verwenden, was Sie wollen. Verwenden Sie dann dieses neue Serializer-Feld in Ihrem übergeordneten Serializer als:
class ParentSerializer(ModelSerializer):
child = RelatedFieldAlternative(queryset=Child.objects.all(), serializer=ChildSerializer)
class Meta:
model = Parent
fields = '__all__'
Ursprünglicher Beitrag
Die Verwendung von zwei verschiedenen Bereichen wäre ok (wie @ Kevin Brown und @joslarson erwähnt), aber ich denke , es ist nicht perfekt (für mich). Da das Abrufen von Daten von einem Schlüssel ( child) und das Senden von Daten an einen anderen Schlüssel ( child_id) für Front-End- Entwickler möglicherweise etwas mehrdeutig ist . (überhaupt keine Beleidigung)
Also, was ich hier vorschlage, ist, die to_representation()Methode zu überschreiben, mit der ParentSerializerder Job erledigt wird.
def to_representation(self, instance):
response = super().to_representation(instance)
response['child'] = ChildSerializer(instance.child).data
return response
Vollständige Darstellung des Serializers
class ChildSerializer(ModelSerializer):
class Meta:
model = Child
fields = '__all__'
class ParentSerializer(ModelSerializer):
class Meta:
model = Parent
fields = '__all__'
def to_representation(self, instance):
response = super().to_representation(instance)
response['child'] = ChildSerializer(instance.child).data
return response
Vorteil dieser Methode?
Mit dieser Methode benötigen wir keine zwei separaten Felder zum Erstellen und Lesen. Hier können sowohl das Erstellen als auch das Lesen mit dem child Schlüssel erfolgen.
Beispielnutzlast zum Erstellen einer parentInstanz
{
"name": "TestPOSTMAN_name",
"phone_number": 1,
"child": 1
}
Bildschirmfoto
