1

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

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 所必需的方式序列化模型数据。

有任何想法吗?

4

1 回答 1

0

这是我自己的一种hacky解决方案:

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()
    # ...
于 2013-06-17T22:34:42.287 回答