如何使用Django的REST框架嵌套串行

问题描述 投票:0回答:1

我有两个机型的用户和地址。地址模型连接到用户模型OneToOneField。在我来说,我试图更新用户模型,在初始情况下,用户模式的地址字段为空。因此,在第一种情况下当我更新用户模型,我想创建一个地址。在其他情况下,只需要更新地址。如何实现这一目标?

models.py

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)

serializers.py

  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')

views.py

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)

我需要出像下面

{
    "result ": {
        "first_name": "Alwin Lazar V",
        "dp": null,
        "gender": null,
        "marital_status": false,
        "dob": null,
        "email": "[email protected]",
        "mobile": null,
        "address": null
    }
}

提交的地址包含地址对象作为响应。

Request Data Format

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>
python django serialization django-models django-rest-framework
1个回答
2
投票

您可以使用嵌套的串并覆盖update方法:

serializers.py

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
© www.soinside.com 2019 - 2024. All rights reserved.