如何使用 PUT 请求在响应中发送多个字段?
How to send several fields in the response with a PUT request?
我希望当我的 PUT 请求成功时,它 return 向我发送一个包含我 PlantSerializer
中所有字段的响应,因为目前响应 return 向我发送了这个:
{
"id":48,
"name":"Jar",
"width":"50",
"height":"50",
"exposure":"None",
"qr_code":"",
"garden":65,
"plant":[
7
]
}
但是,我希望对 return 的回复是:
{
"id":48,
"name":"Jar",
"width":"50",
"height":"50",
"exposure":"None",
"qr_code":"",
"garden":65,
"plant":[
"id":7,
"name":"Artichoke",
"image":null
]
}
我怎样才能达到这个结果?
这是我的序列化器和模型 class :
class Plot(models.Model):
name = models.CharField(max_length=50)
garden = models.ForeignKey('perma_gardens.Garden', on_delete=models.CASCADE)
width = models.CharField(max_length=50, blank=True, null=True)
height = models.CharField(max_length=50, blank=True, null=True)
plant = models.ManyToManyField('perma_plants.Plant', related_name='%(class)s_plant', blank=True)
# Here is my serializers :
class GardenSerializer(serializers.ModelSerializer):
class Meta:
model = Garden
fields = ('id', 'name',)
class PlantSerializer(serializers.ModelSerializer):
class Meta:
model = Plant
fields = ('id', 'name', 'image')
class ReadPlotSerializer(serializers.ModelSerializer):
garden = GardenSerializer(required=True)
plant = PlantSerializer(many=True)
id = serializers.IntegerField(read_only=True)
class Meta:
model = Plot
fields = '__all__'
read_only_fields = [fields]
class WritePlotSerializer(serializers.ModelSerializer):
class Meta:
model = Plot
fields = '__all__'
这是我的观点:
class PlotViewSet(viewsets.ModelViewSet):
queryset = Plot.objects.all()
def create(self, request, *args, **kwargs):
serializer = WritePlotSerializer(data=request.data, many=isinstance(request.data, list))
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk):
snippet = self.get_object(pk)
snippet.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
def partial_update(self, request, *args, **kwargs):
instance = self.queryset.get(pk=kwargs.get('pk'))
serializer = WritePlotSerializer(instance, data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)
def get_serializer_class(self):
if self.action in ("list", "retrieve"):
return ReadPlotSerializer
return WritePlotSerializer
在函数 partial_update
中,您正在使用 WritePlotSerializer
,它仅通过 fields=__all__
值隐式包含 plant
字段。这可能导致 drf 使用 PrimaryKeyRelatedField
,因此您不会获得在 PlantSerializer
.
中定义的所有额外字段
如果我理解 correctyl,您希望在更新中使用 WritePlotSerializer
,但在返回对象时使用 ReadPlotSerializer
。您可能应该通过覆盖 update
方法将它们组合在一个序列化程序中,以支持更新嵌套的 Plant
对象。这里是 related documentation.
或者,如果您不想更新 Plants
值,您可以在所有调用中使用稍微修改过的 ReadPlotSerializer
版本:
class PlotSerializer(serializers.ModelSerializer):
garden = GardenSerializer(required=True, read_only=True)
plant = PlantSerializer(many=True, read_only=True)
id = serializers.IntegerField(read_only=True)
class Meta:
model = Plot
fields = '__all__'
我希望当我的 PUT 请求成功时,它 return 向我发送一个包含我 PlantSerializer
中所有字段的响应,因为目前响应 return 向我发送了这个:
{
"id":48,
"name":"Jar",
"width":"50",
"height":"50",
"exposure":"None",
"qr_code":"",
"garden":65,
"plant":[
7
]
}
但是,我希望对 return 的回复是:
{
"id":48,
"name":"Jar",
"width":"50",
"height":"50",
"exposure":"None",
"qr_code":"",
"garden":65,
"plant":[
"id":7,
"name":"Artichoke",
"image":null
]
}
我怎样才能达到这个结果?
这是我的序列化器和模型 class :
class Plot(models.Model):
name = models.CharField(max_length=50)
garden = models.ForeignKey('perma_gardens.Garden', on_delete=models.CASCADE)
width = models.CharField(max_length=50, blank=True, null=True)
height = models.CharField(max_length=50, blank=True, null=True)
plant = models.ManyToManyField('perma_plants.Plant', related_name='%(class)s_plant', blank=True)
# Here is my serializers :
class GardenSerializer(serializers.ModelSerializer):
class Meta:
model = Garden
fields = ('id', 'name',)
class PlantSerializer(serializers.ModelSerializer):
class Meta:
model = Plant
fields = ('id', 'name', 'image')
class ReadPlotSerializer(serializers.ModelSerializer):
garden = GardenSerializer(required=True)
plant = PlantSerializer(many=True)
id = serializers.IntegerField(read_only=True)
class Meta:
model = Plot
fields = '__all__'
read_only_fields = [fields]
class WritePlotSerializer(serializers.ModelSerializer):
class Meta:
model = Plot
fields = '__all__'
这是我的观点:
class PlotViewSet(viewsets.ModelViewSet):
queryset = Plot.objects.all()
def create(self, request, *args, **kwargs):
serializer = WritePlotSerializer(data=request.data, many=isinstance(request.data, list))
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk):
snippet = self.get_object(pk)
snippet.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
def partial_update(self, request, *args, **kwargs):
instance = self.queryset.get(pk=kwargs.get('pk'))
serializer = WritePlotSerializer(instance, data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)
def get_serializer_class(self):
if self.action in ("list", "retrieve"):
return ReadPlotSerializer
return WritePlotSerializer
在函数 partial_update
中,您正在使用 WritePlotSerializer
,它仅通过 fields=__all__
值隐式包含 plant
字段。这可能导致 drf 使用 PrimaryKeyRelatedField
,因此您不会获得在 PlantSerializer
.
如果我理解 correctyl,您希望在更新中使用 WritePlotSerializer
,但在返回对象时使用 ReadPlotSerializer
。您可能应该通过覆盖 update
方法将它们组合在一个序列化程序中,以支持更新嵌套的 Plant
对象。这里是 related documentation.
或者,如果您不想更新 Plants
值,您可以在所有调用中使用稍微修改过的 ReadPlotSerializer
版本:
class PlotSerializer(serializers.ModelSerializer):
garden = GardenSerializer(required=True, read_only=True)
plant = PlantSerializer(many=True, read_only=True)
id = serializers.IntegerField(read_only=True)
class Meta:
model = Plot
fields = '__all__'