使用Django NestedFields序列化程序时出现AttributeError

2024-04-20 10:15:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个型号:你知道吗

class Users(models.Model):
    first_name = models.CharField(max_length=255)
    middle_name = models.CharField(max_length=255)


class UserAddress(models.Model):
    line1 = models.CharField(max_length=255)
    country = models.CharField(max_length=255)
    user = models.ForeignKey(Users)

用户模型和用户地址模型。下面是两个序列化程序。你知道吗

class UserAddressSerializer(ModelSerializer):

    class Meta:
        model = UserAddress
        exclude = ('id', 'user')


class UserSerializer(ModelSerializer):
    address = UserAddressSerializer(many=True)

    class Meta:
        model = Users
        fields = '__all__'

    def create(self, validated_data):
        address = validated_data.pop('address', [])
        user = Users.objects.create(**validated_data)

        for ad in address:
            UserAddress.objects.create(user=user, **ad)

        return user

我从客户那里收到的数据是

{
  "first_name": "string",
  "last_name": "string",
  "address": [{
     "line1": "asd",
     "country": "asd",
  }],
}

这就是我如何创建一个新用户及其相应的地址。你知道吗

class UserCreate(GenericAPIView):

    serializer_class = UserSerializer

    def post(self, request, *args, **kwargs):

        data = request.data
        serializer = UserSerializer(data=data)
        if not serializer.is_valid():
            return

        user = serializer.save()
        response = {
            'user_id': user.uuid
        }
        return

现在,在获得用户详细信息后,我收到一个错误消息

AttributeError: Got AttributeError when attempting to get a value for field `address` on serializer `UserSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Users` instance.
Original exception text was: 'Users' object has no attribute 'address'.

这就是我获取用户详细信息的方式,包括地址。你知道吗

class UserDetails(GenericAPIView):
    queryset = Users.objects.all()
    serializer_class = UserSerializer
    lookup_field = 'uuid'

    def get(self, request, uuid, *args, **kwargs):
        user = Users.get_user(uuid)
        if not user:
            return 

        serializer = UserSerializer(instance=user)
        return

我读过this example的嵌套关系,我也是这么做的。为什么会出现错误?你知道吗

另外,使用一些DRF mixin是否可以进一步缩短代码(以更干净的方式)?如果是,那怎么办?


Tags: 用户namedatareturnuuidaddressmodelslength
1条回答
网友
1楼 · 发布于 2024-04-20 10:15:26

我认为最简单的解决方案是:在模型UserAddress中添加related_name='address'

class UserAddress(models.Model):
    line1 = models.CharField(max_length=255)
    country = models.CharField(max_length=255)
    user = models.ForeignKey(Users, related_name='address')
    #                                 ^^^^^^^^^^^^^^^

或者可以在序列化程序中添加源属性:

class UserSerializer(ModelSerializer):
    address = UserAddressSerializer(source='useraddress_set', many=True)

序列化程序尝试在模型User中查找属性'address',但默认情况下,它是modelname underline set(useraddress_set,在您的示例中),您可以尝试其他名称,因此可以在模型中设置或按源指定。你知道吗

在本例中,您可以查看models并找到related_name='tracks'

相关问题 更多 >