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)

你可能感兴趣的:(WEB)