Django REST Framework的可写嵌套模型序列化

DRF 可写的嵌套(DRF Writable Nested)
DRF Writable Nested 是Django REST框架的可写嵌套模型序列化器,它允许您使用相关嵌套数据创建/更新模型。
支持下列关系:
OneToOne (direct/reverse)-----一对一(直接的/反向)
ForeignKey (direct/reverse)-----一对多(直接的/反向)
ManyToMany (direct/reverse excluding m2m relations with through model)-----多对多(直接/反向不包括通过模型的m2m关系)
GenericRelation (this is always only reverse)-----一般关系(这总是反过来的)

Requirements(需求)
Python (2.7, 3.5, 3.6)
Django (1.9, 1.10, 1.11, 2.0)
djangorestframework (3.5+)

Installation(安装)

[Shell] 纯文本查看 复制代码

?

1

pip install drf-writable-nested



Usage(用法)
例如,对于以下模型结构:

[Python] 纯文本查看 复制代码

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

from django.db import models

 

 

class Site(models.Model):

    url = models.CharField(max_length=100)

 

 

class User(models.Model):

    username = models.CharField(max_length=100)

 

 

class AccessKey(models.Model):

    key = models.CharField(max_length=100)

 

 

class Profile(models.Model):

    sites = models.ManyToManyField(Site)

    user = models.OneToOneField(User)

    access_key = models.ForeignKey(AccessKey, null=True)

 

 

class Avatar(models.Model):

    image = models.CharField(max_length=100)

    profile = models.ForeignKey(Profile, related_name='avatars')


我们应该创建以下序列化器列表:

[Python] 纯文本查看 复制代码

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

from rest_framework import serializers

from drf_writable_nested import WritableNestedModelSerializer

 

class AvatarSerializer(serializers.ModelSerializer):

    image = serializers.CharField()

 

    class Meta:

        model = Avatar

        fields = ('pk', 'image',)

 

 

class SiteSerializer(serializers.ModelSerializer):

    url = serializers.CharField()

 

class Meta:

    model = Site

    fields = ('pk', 'url',)

 

 

class AccessKeySerializer(serializers.ModelSerializer):

 

    class Meta:

        model = AccessKey

        fields = ('pk', 'key',)

 

 

class ProfileSerializer(WritableNestedModelSerializer):

    # Direct ManyToMany relation

    sites = SiteSerializer(many=True)

 

    # Reverse FK relation

    avatars = AvatarSerializer(many=True)

 

    # Direct FK relation

    access_key = AccessKeySerializer(allow_null=True)

 

    class Meta:

        model = Profile

        fields = ('pk', 'sites', 'avatars', 'access_key',)

 

 

class UserSerializer(WritableNestedModelSerializer):

    # Reverse OneToOne relation

    profile = ProfileSerializer()

 

    class Meta:

        model = User

        fields = ('pk', 'profile', 'username',)




另外,如果您想只支持创建或更新逻辑,您可以使用这个包中的NestedCreateMixin或NestedUpdateMixin。
例如,我们可以将以下带有相关嵌套字段的数据传递给我们的主序列化器:
 

[Python] 纯文本查看 复制代码

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

data = {

    'username': 'test',

    'profile': {

        'access_key': {

            'key': 'key',

        },

        'sites': [

            {

                'url': 'http://google.com',

            },

            {

                'url': 'http://yahoo.com',

            },

        ],

        'avatars': [

            {

                'image': 'image-1.png',

            },

            {

                'image': 'image-2.png',

            },

        ],

    },

}

 

user_serializer = UserSerializer(data=data)

user_serializer.is_valid(raise_exception=True)

user = user_serializer.save()


这个序列化器将自动创建所有嵌套的关系,我们将收到一个完整的实例,其中包含已填充的数据。

[Python] 纯文本查看 复制代码

?

1

2

user_serializer = UserSerializer(instance=user)

print(user_serializer.data)

 

[Python] 纯文本查看 复制代码

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

{

    'pk': 1,

    'username': 'test',

    'profile': {

        'pk': 1,

        'access_key': {

            'pk': 1,

            'key': 'key'

        },

        'sites': [

            {

                'pk': 1,

                'url': 'http://google.com',

            },

            {

                'pk': 2,

                'url': 'http://yahoo.com',

            },

        ],

        'avatars': [

            {

                'pk': 1,

                'image': 'image-1.png',

            },

            {

                'pk': 2,

                'image': 'image-2.png',

            },

        ],

    },

}


还可以通过调用基序列化器的save方法将值传递给嵌套的序列化器。这些kwarg必须是dict类型。

[Python] 纯文本查看 复制代码

?

1

2

3

4

5

6

7

# user_serializer created with 'data' as above

user = user_serializer.save(

    profile={

        'access_key': {'key': 'key2'},

    },

)

print(user.profile.access_key.key)

 

[Python] 纯文本查看 复制代码

?

1

'key2'


注意:相同的值将用于所有嵌套实例,比如默认值,但是优先级更高。
已知的解决方案问题
更新时带有唯一字段的嵌套序列化器的验证问题
我们有一种特殊的mixin单字段smixin可以解决这个问题。mixin将uniquevalidator从验证阶段移动到保存阶段。
如果你想知道更多的细节,你可以阅读相关的问题和文章:

https://github.com/beda-software/drf-writable-nested/issues/1
http://www.django-rest-framework.org/api-guide/validators/#updating-nested-serializers
使用的例子:

[Python] 纯文本查看 复制代码

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

class Child(models.Model):

    field = models.CharField(unique=True)

 

 

class Parent(models.Model):

    child = models.ForeignKey('Child')

 

 

class ChildSerializer(UniqueFieldsMixin, serializers.ModelSerializer):

    class Meta:

        model = Child

 

 

class ParentSerializer(NestedUpdateMixin, serializers.ModelSerializer):

    child = ChildSerializer()

 

    class Meta:

        model = Parent


注意:UniqueFieldsMixin必须仅应用于具有唯一字段的序列化程序。

Mixin ordering
当您同时使用mixin (UniqueFieldsMixin和NestedCreateMixin或NestedUpdateMixin)时,您应该将UniqueFieldsMixin放在前面。

例如:

[Python] 纯文本查看 复制代码

?

1

2

class ChildSerializer(UniqueFieldsMixin, NestedUpdateMixin,

        serializers.ModelSerializer):



(文章转载自https://www.jianshu.com/p/c057877d26e1)

你可能感兴趣的:(python)