django rest框架通过POST创建嵌套对象"模型"

sko*_*opp 25 django django-rest-framework

我正在尝试POST一个新的嵌套对象,问题只是创建"顶部"对象(播放列表),但不要创建"ChannelItem"...

我的模特:

class Playlist(models.Model):
    provider = models.IntegerField()
    channel_id = models.CharField(max_length=100)
    channel_version = models.CharField(blank=True, max_length=100)
    start = models.DateTimeField()
    url = models.CharField(max_length=500)


class ChannelItem(models.Model):
    playlist = models.ForeignKey(Playlist, editable=False, related_name='channelitems')
    content_id = models.CharField(max_length=100)
    content_version = models.CharField(blank=True, max_length=100)
Run Code Online (Sandbox Code Playgroud)

我的序列化器:

class ChannelItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = ChannelItem
        fields = ('content_id', 'content_version')
        exclude = ('id')
        depth = 1


class PlaylistSerializer(serializers.ModelSerializer):

    class Meta:
        model = Playlist
        fields = ('id', 'provider', 'channel_id', 'channel_version', 'start', 
                  'url', 'channelitems')
        depth = 2

channelitems = ChannelItemSerializer()
Run Code Online (Sandbox Code Playgroud)

我使用curl发布以下数据:

'{"provider":125,"channel_id":"xyz", "channel_version":"xsqt", 
"start":"2012-12-17T11:04:35","url":"http://192.168.1.83:8080/maaaaa",
"channelitems":[{"content_id":"0.flv", "content_version":"ss"},
{"content_id":"1.flv","content_version":"ss"}]}' http://localhost:8000/playlist_scheduler/playlists/
Run Code Online (Sandbox Code Playgroud)

我收到的消息是:

HTTP/1.1 201 CREATED
Content-Type: application/json
Transfer-Encoding: chunked
Date: Mon, 17 Dec 2012 20:12:54 GMT
Server: 0.0.0.0

{"id": 25, "provider": 125, "channel_id": "xyz", "channel_version": "xsqt",
"start":"2012-12-17T11:04:35", "url": "http://localhost:8080/something",
"channelitems": []}
Run Code Online (Sandbox Code Playgroud)

Tom*_*tie 21

嵌套表示当前不支持读写,而应该是只读的.

您应该考虑使用平面表示,使用pk或超链接关系.

如果需要嵌套表示,则可能需要考虑使用两个单独的端点 - 平面可写端点和嵌套只读端点.

  • 它会来 :) (8认同)
  • 我已经在REST框架文档中看到过术语平面表示也多次使用过,但是你能举一个例子来说明这意味着什么吗?我完全理解嵌套的序列化器,但我需要读写,而不仅仅是读取.我的选择似乎是扁平化表示,或编写我自己的自定义RelatedField? (7认同)

Mic*_*eri 6

如果有人需要一个快速而肮脏的解决方案,我想出了一个我将暂时在项目中使用的方法:

class NestedManyToManyField(serializers.WritableField):
    def to_native(self, value):
        serializer = self.Meta.serializer(value.all(), many=True, context=self.context)
        return serializer.data
    def from_native(self, data):
        serializer = self.Meta.serializer(data=data, many=True, context=self.context)
        serializer.is_valid()
        serializer.save()
        return serializer.object
    class Meta:
        serializer = None
Run Code Online (Sandbox Code Playgroud)

然后创建自己的子类NestedManyToManyField:

class TopicNestedSerializer(NestedManyToManyField):
    class Meta:
        serializer = MyOriginalSerializer
Run Code Online (Sandbox Code Playgroud)

一个例子MyOriginalSerializer:

class MyOriginalSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.MyModel
        fields = ('id', 'title',)
Run Code Online (Sandbox Code Playgroud)

到目前为止,这对我来说很好.但要注意有一些干净的修复: