Django REST framework 嵌套关系的数据保存(Writable nested serializers)

利用Django REST framework   能很方便的对Django的model嵌套关系进行展示。嵌套关系的展示通过在序列化类中的depth属性来设置,depth表示嵌套关系展开的层数。比如,Djiango自带的User 模型。User关联了Groups ,同时,Groups又关联了Permission。序列化类定义如下:

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'
        depth = 2

得到的json数据将进行2层的嵌套关系的展开,结果如下:

{
    "id": 1,
    "username": "admin",
     ... ...
    "groups": [
        {
            "id": 1,
            "name": "test111",
            "permissions": [
                {
                    "id": 28,
                    "name": "Can add 联系人信息",
                    "codename": "add_customercontact",
                    "content_type": 10
                },
                {
                    "id": 61,
                    "name": "Can add market info",
                    "codename": "add_marketinfo",
                    "content_type": 21
                },
                {
                    "id": 62,
                    "name": "Can change market info",
                    "codename": "change_marketinfo",
                    "content_type": 21
                }
            ]
        }
    ],
    "user_permissions": [
        {
            "id": 1,
            "name": "Can add log entry",
            "codename": "add_logentry",
            "content_type": {
                "id": 1,
                "app_label": "admin",
                "model": "logentry"
            }
        }
        ... ...
    ]
}

虽然这种模式很方便的对数据进行了嵌套展示,但是也带来了一个问题,无法对数据进行保存和更新。

文档中说明了:

To use writable nested serialization you'll want to declare a nested field on the serializer class, and write the create() and/or update() methods explicitly.

文档中提供的方法,但是感觉不好用。于是,采用了下面这种方式。创建两个序列化类,一个有depth,一个没有depth,如下:

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'
        depth = 2

   class UserSerializerNodepth(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'
然后在ViewSet中,重载create方法,如下:
  1  def create(self, request):
  2         serialized = UserSerializerNoDepth(data=request.data)
  3         if serialized.is_valid():
  4             serialized.save()
  5             return Response(serialized.data)
  6         else:
  7             return Response(serialized.errors)

关键点在第2行,即利用UserSerializerNoDepth对数据进行序列化,而不是用ViewSet原来指定的UserSerializer进行序列化。这样就能在统一的路由下查看展开的嵌套数据,又能进行数据的保存了。update也是同样的方式:

  1 def update(self, request,pk=None):
  2         user=  self.get_object()
  3         serialized = UserSerializerNoDepth(user,data=request.data)
  4         if serialized.is_valid():
  5             serialized.save()
  6             return Response(serialized.data)
  7         else:
  8             return Response(serialized.errors,status=status.HTTP_400_BAD_REQUEST)
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值