Django 使用序列化程序创建扩展用户
Django Create Extended User with Serializer
我正在努力将基本用户模型扩展到其他字段。我创建了一个应该有 OneToOneRelation
的配置文件模型。我正在使用序列化程序。现在,当我尝试 post 虚拟用户时,出现此错误:
**TypeError: User() got an unexpected keyword argument 'street'**
如果我只发送用户,效果很好。我知道 'street' 参数不是用户的一部分,而是应该稍后存储的配置文件的一部分。
我试图用每个值的 'request.POST.pop' 来解决这个问题,并解析为 dict
,但是没有数据被传输。此外,我在 Signals 上没有成功。
有谁知道我该如何进行这项工作,因为用户和配置文件将同时创建?用户必须先保存并将其生成的 ID 传递给引用它的配置文件。
Models.py:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=CASCADE, null=True)
street = models.CharField(name="street", max_length=100)
number = models.CharField(name="number", max_length=10)
plz = models.CharField(name="plz", max_length=10)
city = models.CharField(name="city", max_length=100)
phone = models.CharField(name="phone", max_length=20)
locked = models.BooleanField(name="locked", default=False)
Serializer.py:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = '__all__'
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = ['street', 'number', 'plz', 'city', 'phone']
Views.py:
@api_view(['POST'])
def userCreate(request):
userSerializer = UserSerializer(data=request.data)
if userSerializer.is_valid():
user = userSerializer.create(validated_data=request.data)
profileSerializer = ProfileSerializer(instance=user ,data=request.data)
if profileSerializer.is_valid():
profileSerializer.create()
return Response(status=status.HTTP_200_OK)
return Response(status=status.HTTP_400_BAD_REQUEST)
您可以重写序列化程序以包含配置文件。然后覆盖 create
方法。
class UserSerializer(serializers.ModelSerializer):
profile = ProfileSerializer()
class Meta:
model = User
fields = '__all__'
def create(self, validated_data):
profile_data = validated_data.pop('profile')
user = User.objects.create(**validated_data)
Profile.objects.create(**profile_data, user=user)
return user
那么你的观点就变成了:
@api_view(['POST'])
def userCreate(request):
userSerializer = UserSerializer(data=request.data)
if userSerializer.is_valid():
user = userSerializer.save()
return Response(status=status.HTTP_200_OK)
return Response(status=status.HTTP_400_BAD_REQUEST)
对服务器的请求应修改为:
{
profile: {
... // profile specific attributes like street, number, city
},
... // user specific attibutes
}
PS: 要更新实例,你应该覆盖序列化器的update
方法。
我正在努力将基本用户模型扩展到其他字段。我创建了一个应该有 OneToOneRelation
的配置文件模型。我正在使用序列化程序。现在,当我尝试 post 虚拟用户时,出现此错误:
**TypeError: User() got an unexpected keyword argument 'street'**
如果我只发送用户,效果很好。我知道 'street' 参数不是用户的一部分,而是应该稍后存储的配置文件的一部分。
我试图用每个值的 'request.POST.pop' 来解决这个问题,并解析为 dict
,但是没有数据被传输。此外,我在 Signals 上没有成功。
有谁知道我该如何进行这项工作,因为用户和配置文件将同时创建?用户必须先保存并将其生成的 ID 传递给引用它的配置文件。
Models.py:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=CASCADE, null=True)
street = models.CharField(name="street", max_length=100)
number = models.CharField(name="number", max_length=10)
plz = models.CharField(name="plz", max_length=10)
city = models.CharField(name="city", max_length=100)
phone = models.CharField(name="phone", max_length=20)
locked = models.BooleanField(name="locked", default=False)
Serializer.py:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = '__all__'
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = ['street', 'number', 'plz', 'city', 'phone']
Views.py:
@api_view(['POST'])
def userCreate(request):
userSerializer = UserSerializer(data=request.data)
if userSerializer.is_valid():
user = userSerializer.create(validated_data=request.data)
profileSerializer = ProfileSerializer(instance=user ,data=request.data)
if profileSerializer.is_valid():
profileSerializer.create()
return Response(status=status.HTTP_200_OK)
return Response(status=status.HTTP_400_BAD_REQUEST)
您可以重写序列化程序以包含配置文件。然后覆盖 create
方法。
class UserSerializer(serializers.ModelSerializer):
profile = ProfileSerializer()
class Meta:
model = User
fields = '__all__'
def create(self, validated_data):
profile_data = validated_data.pop('profile')
user = User.objects.create(**validated_data)
Profile.objects.create(**profile_data, user=user)
return user
那么你的观点就变成了:
@api_view(['POST'])
def userCreate(request):
userSerializer = UserSerializer(data=request.data)
if userSerializer.is_valid():
user = userSerializer.save()
return Response(status=status.HTTP_200_OK)
return Response(status=status.HTTP_400_BAD_REQUEST)
对服务器的请求应修改为:
{
profile: {
... // profile specific attributes like street, number, city
},
... // user specific attibutes
}
PS: 要更新实例,你应该覆盖序列化器的update
方法。