AttributeError - 使用Django NestedFields序列化程序时

时间:2017-10-26 06:58:52

标签: python django django-rest-framework

我有2个型号: -

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)

用户模型&用户地址模型。以下是2个序列化器。

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 mixins可以缩短这些代码(以更好的清洁方式)吗?如果是,那怎么做?

1 个答案:

答案 0 :(得分:1)

我认为针对您的案例最简单的解决方案是:在模型中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')
    #                                 ^^^^^^^^^^^^^^^

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

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

序列化程序尝试查找属性'地址'在模型User中,但默认情况下,它是modelname下划线集(在您的情况下为useraddress_set),并且您尝试其他名称,因此您可以在模型中设置或按源指定。

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