django休息框架嵌套字段与多个模型 [英] django rest framework nested fields with multiple models

查看:131
本文介绍了django休息框架嵌套字段与多个模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是django和django休息框架。我有两个型号:用户和手机。

This is django and django rest framework. I have 2 models: User and phone.


第一个问题:

The 1st problem:

我想要能够更新用户数据(电子邮件)旁边的电话
数据(电话号码)在一个单一的api更新响应。电话号码可以
为0或许多。好吧,像partial = True。如果用户只想要
更新电话号码,请不要更新电子邮件,反之亦然。

I want to be able to update user data(email) alongside phone data(phone numbers) in 1 single api update response. Phone number can be 0 or many. Well, like partial=True actually. 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:

如何序列化多个phone_numbers并保存到db?

How to serialize multiple phone_numbers and save to 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')

html表单将在电话号码字段上加号,表示可以添加新的电话号码。例如 here

The html form would have plus sign at the phone number field to indicate a new phone number can be added. example is here

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

预期的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'
}

或可能

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

或可能

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

这个json可以做吗?
怎么可以串行器和modelviewset呢?
抱歉我是drf的新手。

is this json possible to do? how can serializer and modelviewset do it? sorry I'm totally new to drf

推荐答案


  1. 任何嵌套对象的默认版本

您需要添加序列化程序创建更新方法:

You need to add serializer create and update methods:

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

请求创建:

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

请求更新:

{"phones": [{"phone_number": 22}]}




  1. 当前结构优化:

  1. Optimization for current structure:
    • do not store phone as int field - better string.
    • accept phones as list of strings, use ListField (http://www.django-rest-framework.org/api-guide/fields/#listfield), handle creation and updation in serializer methods.

更新


  1. phone_data = validated_data.pop('phones') - > phones_data = validated_data.pop('phones',[]),处理案例if

  1. phones_data = validated_data.pop('phones') -> phones_data = validated_data.pop('phones', []), to handle case if there are no phones in request.


应该在模型视图中完成电话更新和创建吗?

Should phone updates and creation be done in modelviewset?

否,序列化程序负责转换本地数据 - >内部对象。所以如果它接收电话数据 - 它应该创建 PhoneNumber 对象。

No, serializer is responsible of transformation native data -> internal objects. So if it receive phones data - it should create PhoneNumber objects.

这篇关于django休息框架嵌套字段与多个模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆