This is django and django rest framework. I have 2 models: User and phone.
The 1st problem:
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:
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')
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 : [email protected]
phone number: 23423432423
(add more)
phone number: 3423423423
(add more)
...
The expected json
{
'email': '[email protected]',
'phone_number': '32432433223234'
}
or if many phone numbers are added
{
'email': '[email protected]',
'phone_number': '32432433223234',
'phone_number': '324342322342323'
}
or maybe
{
'email': '[email protected]',
'phone_number': ['32432433223234','324342322342323']
}
or maybe
{
'email': '[email protected]',
'Phone': [{'id': 1, 'phone_number': '32432433223234'}, {'id': 2, 'phone_number': '324342322342323'}]
}
is this json possible to do? how can serializer and modelviewset do it? sorry I'm totally new to drf
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
Request for creation:
{"email": "[email protected]" "phones": [{"phone_number": 12}, {"phone_number": 123}]}
Request for update:
{"phones": [{"phone_number": 22}]}
ListField
(http://www.django-rest-framework.org/api-guide/fields/#listfield), handle creation and updation in serializer methods.UPDATE
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?
No, serializer is responsible of transformation native data -> internal objects
. So if it receive phones data - it should create PhoneNumber
objects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With