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

网友投稿 1346 2022-10-14

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

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

DRF Writable Nested

This is a writable nested model serializer for Django REST Framework which allows you to create/update your models with related nested data.

The following relations are supported:

OneToOne (direct/reverse)ForeignKey (direct/reverse)ManyToMany (direct/reverse excluding m2m relations with through model)GenericRelation (this is always only reverse)

Requirements

Python (3.5, 3.6, 3.7, 3.8)Django (2.2, 3.0)djangorestframework (3.8+)

Installation

pip install drf-writable-nested

Usage

For example, for the following model structure:

from django.db import modelsclass 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')

We should create the following list of serializers:

from rest_framework import serializersfrom drf_writable_nested.serializers import WritableNestedModelSerializerclass 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',)

Also, you can use NestedCreateMixin or NestedUpdateMixin from this package if you want to support only create or update logic.

For example, we can pass the following data with related nested fields to our main serializer:

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()

This serializer will automatically create all nested relations and we receive a complete instance with filled data.

user_serializer = UserSerializer(instance=user)print(user_serializer.data)

{ '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', }, ], },}

It is also possible to pass through values to nested serializers from the call to the base serializer's save method. These kwargs must be of type dict. E g:

# user_serializer created with 'data' as aboveuser = user_serializer.save( profile={ 'access_key': {'key': 'key2'}, },)print(user.profile.access_key.key)

'key2'

Note: The same value will be used for all nested instances like default value but with higher priority.

Known problems with solutions

Validation problem for nested serializers with unique fields on update

We have a special mixin UniqueFieldsMixin which solves this problem. The mixin moves UniqueValidator's from the validation stage to the save stage.

If you want more details, you can read related issues and articles: https://github.com/beda-software/drf-writable-nested/issues/1 http://django-rest-framework.org/api-guide/validators/#updating-nested-serializers

Example of usage:

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 = Childclass ParentSerializer(NestedUpdateMixin, serializers.ModelSerializer): child = ChildSerializer() class Meta: model = Parent

Note: UniqueFieldsMixin must be applied only on serializer which has unique fields.

Mixin ordering

When you are using both mixins (UniqueFieldsMixin and NestedCreateMixin or NestedUpdateMixin) you should put UniqueFieldsMixin ahead.

For example:

class ChildSerializer(UniqueFieldsMixin, NestedUpdateMixin, serializers.ModelSerializer):

Authors

2014-2020, beda.software

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Build-CoucbDB- CouchDB自动安装程序
下一篇:集合框架_可变参数的概
相关文章

 发表评论

暂时没有评论,来抢沙发吧~