这是django和django休息框架。我有2个型号:用户和手机。
第一个问题:
我希望能够在手机旁更新用户数据(电子邮件) 单个api更新响应中的数据(电话号码)。电话号码可以 是0或许多。好吧,就像partial = True一样。如果用户只是想要 更新电话号码,不要更新电子邮件,反之亦然。
其他信息:在注册时,不包括电话。只是基本的用户信息(姓氏,名字,电子邮件,密码)。注册完成后,手机只能在用户个人资料表格中更新。用户个人资料表单实际上是链接到多个模型,即用户和电话
第二个问题:
如何序列化多个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')
html表单会在电话号码字段中显示加号,表示可以添加新的电话号码。示例是here
email : admin@admin.com
phone number: 23423432423
(add more)
phone number: 3423423423
(add more)
...
预期的json
{
'email': 'email@email.com',
'phone_number': '32432433223234'
}
或添加了多个电话号码
{
'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有可能吗? serializer和modelviewset怎么做呢? 对不起,我对drf来说是全新的
答案 0 :(得分:10)
您需要添加序列化器create
和update
方法:
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}]}
ListField
(http://www.django-rest-framework.org/api-guide/fields/#listfield),处理序列化方法中的创建和更新。<强>更新强>
phones_data = validated_data.pop('phones')
- &gt; phones_data = validated_data.pop('phones', [])
,如果请求中没有电话,则处理案例。
应该在modelviewset中完成手机更新和创建吗?
不,序列化程序负责转换native data -> internal objects
。因此,如果它接收电话数据 - 它应该创建PhoneNumber
个对象。