Django Rest框架在POST中接收主键值,并将模型对象作为嵌套的serializ返回

2024-04-29 21:25:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我不完全确定我的问题的标题是否如我所希望的那样具体,但事实是这样的:

我有一个HyperlinkedModelSerializer看起来像这样:

class ParentArrivalSerializer(serializers.HyperlinkedModelSerializer):
    carpool = SchoolBuildingCarpoolSerializer()

    class Meta:
        model = ParentArrival

如您所见,carpool被定义为一个嵌套的序列化器对象,我想要的是能够发出POST请求,以这种方式创建一个ParentArrival(数据作为application/json):

{
    ...
    "carpool": "http://localhost:8000/api/school-building-carpools/10/"
    ...
}

以这种方式接收数据:

{
    "carpool": {
        "url": "http://localhost:8000/api/school-building-carpools/10/"
        "name": "Name of the carpool",
        ...
    }
}

基本上,我在寻找一种方法来处理嵌套序列化器,而不必在POST请求中将数据作为对象(在本例中是id或url)发送,而是将对象作为嵌套在序列化响应中接收。


Tags: 数据对象apilocalhosthttp序列化方式post
3条回答

我对我之前的解决方案很满意,但我决定再看一次,我想我有另一个解决方案,完全符合你的要求。

基本上,您需要创建自己的自定义字段,并覆盖to_representation方法:

class CarpoolField(serializers.PrimaryKeyRelatedField):
    def to_representation(self, value):
        pk = super(CarpoolField, self).to_representation(value)
        try:
           item = ParentArrival.objects.get(pk=pk)
           serializer = CarpoolSerializer(item)
           return serializer.data
        except ParentArrival.DoesNotExist:
           return None

    def get_choices(self, cutoff=None):
        queryset = self.get_queryset()
        if queryset is None:
            return {}

        return OrderedDict([(item.id, str(item)) for item in queryset])

class ParentArrivalSerializer(serializers.HyperlinkedModelSerializer):
    carpool = CarpoolField(queryset=Carpool.objects.all())

    class Meta:
        model = ParentArrival

这将允许您使用

{
     "carpool": 10
}

得到:

{
    "carpool": {
        "url": "http://localhost:8000/api/school-building-carpools/10/"
        "name": "Name of the carpool",
        ...
    }
}

重写to_representation方法怎么样?

class YourSerializer(serializers.ModelSerializer):

    class Meta:
        model = ModelClass
        fields = ["id", "foreignkey"]

    def to_representation(self, instance):
        data = super(YourSerializer, self).to_representation(instance)
        data['foreignkey'] = YourNestedSerializer(instance.foreignkey).data
        return data

很简单。 如您所知,Django appends "_id" to the field name在ModelClass中,您可以在SerializerClass中实现它,也可以实现原始字段。你要做的就是这样

class ParentArrivalSerializer(serializers.HyperlinkedModelSerializer):
    # ...
    carpool_id = serializers.IntegerField(write_only=True)
    carpool = SchoolBuildingCarpoolSerializer(read_only=True)
    # ...
    class Meta:
        fields = ('carpool_id', 'carpool', ...)

在POST请求中使用carpool_id

相关问题 更多 >