简体   繁体   English

django rest框架具有多个模型的嵌套字段

[英]django rest framework nested fields with multiple models

This is django and django rest framework. 这是django和django休息框架。 I have 2 models: User and phone. 我有2个型号:用户和手机。

The 1st problem: 第一个问题:

I want to be able to update user data(email) alongside phone data(phone numbers) in 1 single api update response. 我希望能够在1个单独的api更新响应中更新用户数据(电子邮件)和电话数据(电话号码)。 Phone number can be 0 or many. 电话号码可以是0或很多。 Well, like partial=True actually. 好吧,就像partial = True一样。 If a user just want to update phone numbers, don't update email and vice versa. 如果用户只想更新电话号码,请不要更新电子邮件,反之亦然。


Additional info: At the time of registering, phone is not included. 附加信息:在注册时,不包括电话。 Just basic user info (last name, first name, email, password). 只是基本的用户信息(姓氏,名字,电子邮件,密码)。 The phone can only get updated in the user profile form after registration is done. 注册完成后,手机只能在用户个人资料表格中更新。 The user profile form is actually linking to multiple models, which is User and Phone 用户配置文件表单实际上链接到多个模型,即用户和电话

The 2nd problem: 第二个问题:

How to serialize multiple phone_numbers and save to db? 如何序列化多个phone_numbers并保存到db?

class User(AbstractBaseUser):
    email = models.EmailField(unique=True, default='')
    USERNAME_FIELD = 'email'


class Phone(models.Model):
    phone_number = models.CharField(max_length=10)
    owner = models.ForeignKey(User)

--------------------------------------
class UserSerializer(serializers.ModelSerializer):
    phone_number = PhoneSerializer(required=False, many=True)

    class Meta:
        model = User
        fields = ('email, 'phone_number')


class PhoneSerializer(serializers.ModelSerializer):

     class Meta:
          Model = Phone
          fields = ('phone_number')

The html form would have plus sign at the phone number field to indicate a new phone number can be added. html表单在电话号码字段中会有加号,表示可以添加新的电话号码。 example is here 例子就在这里

email : admin@admin.com
phone number: 23423432423
(add more)
phone number: 3423423423
(add more)
...

The expected json 预期的json

{
'email': 'email@email.com',
'phone_number': '32432433223234'
}

or if many phone numbers are added 或者如果添加了许多电话号码

{
'email': 'email@email.com',
'phone_number': '32432433223234',
'phone_number': '324342322342323'
}

or maybe 或者可能

{
'email': 'email@email.com',
'phone_number': ['32432433223234','324342322342323']
}

or maybe 或者可能

{
'email': 'email@email.com',
'Phone': [{'id': 1, 'phone_number': '32432433223234'}, {'id': 2, 'phone_number': '324342322342323'}]
}

is this json possible to do? 这个json有可能吗? how can serializer and modelviewset do it? serializer和modelviewset怎么做呢? sorry I'm totally new to drf 抱歉,我对drf完全不熟悉

  1. Default version for any nested objects. 任何嵌套对象的默认版本。

You need to add serializer create and update methods: 您需要添加序列化程序createupdate方法:

class UserSerializer(serializers.ModelSerializer):
    phones = PhoneSerializer(required=False, many=True)

    class Meta:
        model = User
        fields = ('email', 'phone_number')

    def create(self, validated_data):
        phones_data = validated_data.pop('phones', [])
        user = super(UserSerializer, self).create(validated_data)
        for phone_data in phones_data:
            user.phone_set.create(phone_number=phone_data['phone_number'])
        return user

    def update(self, instance, validated_data):
        phones_data = validated_data.pop('phones', [])
        user = super(UserSerializer, self).update(instance, validated_data)
        # delete old
        user.phone_set.exclude(phone__in=[p['phone_number'] for p in phones_data]).delete()
        # create new
        for phone_data in phones_data:
            user.phone_set.get_or_create(phone_number=phone_data['phone_number'])
        return user

Request for creation: 要求创作:

{"email": "test@example.com" "phones": [{"phone_number": 12}, {"phone_number": 123}]}

Request for update: 要求更新:

{"phones": [{"phone_number": 22}]}
  1. Optimization for current structure: 当前结构的优化:

UPDATE UPDATE

  1. phones_data = validated_data.pop('phones') -> phones_data = validated_data.pop('phones', []) , to handle case if there are no phones in request. phones_data = validated_data.pop('phones') - > phones_data = validated_data.pop('phones', []) ,用于处理请求中没有电话的情况。

  2. Should phone updates and creation be done in modelviewset? 手机更新和创建是否应该在modelviewset中完成?

    No, serializer is responsible of transformation native data -> internal objects . 不,序列化程序负责转换native data -> internal objects So if it receive phones data - it should create PhoneNumber objects. 因此,如果它接收电话数据 - 它应该创建PhoneNumber对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM