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方法。