I have two models User and Address. The Address model is connected to User model as OneToOneField. In my case I trying to update the User model, in Initial case the address field of User model is null. So in first case When I update User model, I want to create an Address. In other cases only need to update address. How to achieve this?
class User(AbstractUser):
first_name = models.CharField(max_length=100, blank=True, default=None, null=True)
dp = models.ImageField(upload_to='profiles/', blank=True)
gender = models.CharField(choices=GENDER_TYPE_CHOICES, max_length=10, default=None, blank=True, null=True)
marital_status = models.BooleanField(default=False)
dob = models.DateField(default=None, blank=True, null=True, )
email = models.EmailField(default=None, blank=True, null=True, unique=True)
mobile = PhoneNumberField(blank=True, null=True, unique=True)
fire_token = models.TextField(blank=True, default=None, null=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=True)
def __str__(self):
return str(self.first_name)
class Address(models.Model):
user = models.OneToOneField(User, default=None, null=True, blank=True, related_name="address_user",
on_delete=models.CASCADE)
raw = models.CharField(max_length=100, blank=True, default=None, null=True)
street_number = models.CharField(max_length=100, blank=True, default=None, null=True)
route = models.CharField(max_length=100, blank=True, default=None, null=True)
locality = models.CharField(max_length=100, blank=True, default=None, null=True)
postal_code = models.CharField(max_length=6, blank=True, default=None, null=True)
state = models.CharField(max_length=100, blank=True, default=None, null=True)
state_code = models.CharField(max_length=6, blank=True, default=None, null=True)
country = models.CharField(max_length=100, blank=True, default=None, null=True)
country_code = models.CharField(max_length=6, blank=True, default=None, null=True)
def __str__(self):
return str(self.raw)
class AddressSerializer(ModelSerializer):
class Meta:
model = Address
fields = '__all__'
class UpdateUserProfileSerializer(ModelSerializer):
class Meta:
model = User
fields = ('first_name', 'dp', 'gender', 'marital_status', 'dob', 'address')
class UserProfileAPIView(APIView):
serializer_class = UserProfileSerializer
permission_classes = [IsAuthenticated]
# Get User Profile
def get(self, request):
serializer = UserProfileSerializer(request.user, context={'request': request})
return Response({'result ': serializer.data},
status=status.HTTP_200_OK)
def patch(self, request):
user_serializer = UpdateUserProfileSerializer(request.user, data=request.data, context={'request': request})
if user_serializer.is_valid():
user_serializer.save()
return Response({'response': 'Successfully updated', 'result': user_serializer.data},
status=status.HTTP_200_OK)
else:
return Response(user_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
I need out like below
{
"result ": {
"first_name": "Alwin Lazar V",
"dp": null,
"gender": null,
"marital_status": false,
"dob": null,
"email": "alwinlazar46@gmail.com",
"mobile": null,
"address": null
}
}
The address filed contain address object as response.
first_name: Alwin
gender: m
marital_status: false
raw: <String>
street_number: <String>
route: <String>
locality: <String>
postal_code: <String>
state: <String>
state_code: <String>
country: <String>
country_code: <String>
You can use the nested serializer and override the update
method:
class AddressSerializer(ModelSerializer):
class Meta:
model = Address
exclude = ('user',)
class UpdateUserProfileSerializer(ModelSerializer):
address = AddressSerializer()
class Meta:
model = User
fields = ('first_name', 'dp', 'gender', 'marital_status', 'dob', 'address')
def update(self, instance, validated_data):
address = validated_data.pop('address')
instance = super().update(instance, validated_data)
if hasattr(instance, 'address'):
for key, value in address.items():
setattr(instance.address, key, value)
instance.address.save()
else:
Address.objects.create(user=instance, **address)
return instance
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.