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