如何编写嵌套的序列化程序,在写入或读取时表现不同?

时间:2013-06-17 20:13:35

标签: django-rest-framework

我正在寻找一种创建嵌套序列化程序的方法,在编写或读取时行为会有所不同。在我的具体情况下,我有一些看起来像这样的模型:

class Frame(models.Model):
    frame_stack = models.IntegerField()
    frame_reach = models.IntegerField()
    # ...

class CustomBicycle(models.Model):
    frame = models.ForeignKey(Frame)
    # ...

当CustomBicycle模型被序列化时,我希望它看起来像这样:

{
    "id": 1,
    "frame": {
        "id": 1,
        "frame_stack": 123,
        "frame_reach": 234
    }
}

假设我想提交一些要反序列化的JSON,以便更新上面的CustomBicycle实例。在这种情况下,我想提交以下JSON,以便将其Frame更新为id = 2的那个:

{
    "id": 1,
    "frame": {
        "id": 2,
        "frame_stack": 345,
        "frame_reach": 456
    }
}

我需要的序列化程序将查看JSON中的“frame.id”属性,然后将CustomBicycle实例更新为指向第2帧。它会忽略JSON中“frame”键下的所有其他属性(但它应该允许那些属性存在)。

我想要这个的原因是我在我的应用程序的Javascript中有类似于模型类的东西。我可以轻松地将这些Javascript模型实例序列化为类似于上面的JSON。我不想按照当前版本的Django Rest Framework的要求,以使用平面JSON API所需的方式编写额外的逻辑来序列化模型数据。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

这是我对这个问题的一种黑客解决方案:

class NestedForeignKeyAssignmentMixin(object):
    def field_from_native(self, data, files, field_name, into):
        if self.read_only:
            return

        value = data.get(field_name)
        id = value.get('id') if value else None

        if not id:
            if self.required:
                raise ValidationError(self.error_messages['required'])
            into[field_name] = None
            return

        model = self.Meta.model

        try:
            into[field_name] = model._default_manager.get(id=id)
        except model.DoesNotExist:
            raise ValidationError('{name} with id `{id}` does not exist'.format(
                name=model.__name__,
                id=id,
            ))


class FrameSerializer(NestedForeignKeyAssignmentMixin, serializers.ModelSerializer):
    # ...

    class Meta:
        model = Frame


class CustomBicycleSerializer(serializers.ModelSerializer):
    frame = FrameSerializer()
    # ...