【问题标题】:Saving User details in UserDetail Table using One-To-One Relation Django Rest API使用一对一关系 Django Rest API 在 UserDetail 表中保存用户详细信息
【发布时间】:2021-09-25 00:27:53
【问题描述】:

我是 django 的新手。 我正在尝试通过遵循 Django 文档使用一对一关系将用户详细信息保存在另一个表中,但给了我一个错误

模型.py

class UserDetails(models.Model):
    user=models.OneToOneField(User,on_delete=models.CASCADE)
    phone=models.CharField(max_length=10)
    address=models.CharField(max_length=200,default="")
    created=models.DateTimeField(auto_now_add=True)
    updated=models.DateTimeField(auto_now_add=True)
    objects=models.Manager()
    def __str__(self):
         return self.user.username

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
         UserDetails.objects.create(user=instance,phone="",address="")
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    instance.userdetails.save()

序列化器.py

class UserDetailsSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserDetails
        fields= ['phone','address']
class CreateUserSerializer(serializers.ModelSerializer):
    user=UserDetailsSerializer()
    class Meta:
        model =User
        fields=['id','url','username','email','password','user']

    def create(self, validated_data):
        user_data=validated_data.pop('user')
        user=User.objects.create(**validated_data)
        UserDetails.objects.create(user=user,**user_data)          
    return user

当我在 serializer.py user=UserDetailsSerializer(read_only=True) 中写上面时,否则给我以下错误

在序列化程序 CreateUserSerializer 上尝试获取字段 user 的值时出现 AttributeError。 序列化程序字段可能命名不正确,并且与 User 实例上的任何属性或键都不匹配。 原始异常文本是:“用户”对象没有属性“用户”。

我找到了一种让它工作的方法,但我必须手动定义每个字段,但我希望上面的序列化程序能够工作

工作序列化器.py

class CreateUserSerializer(serializers.HyperlinkedModelSerializer):
    last_login=serializers.ReadOnlyField()
    date_joined=serializers.ReadOnlyField()
    phone=serializers.CharField(source='userdetails.phone')
    address=serializers.CharField(source='userdetails.address')
    updated=serializers.ReadOnlyField(source='userdetails.updated')
    # password=serializers.CharField(style={'input_type':'password'},write_only=True)
    class Meta:
        model = User
        fields=['id','first_name','last_name','username','password','phone','address','url','email','is_superuser','is_staff','last_login','date_joined','updated']
    extra_kwargs={
        'password':{'write_only':True},
    }

def create(self, validated_data):
    userdetails_data=validated_data.pop('userdetails')
    user=User.objects.create_user(**validated_data)
    user.userdetails.phone=userdetails_data.get('phone')
    user.userdetails.address=userdetails_data.get('address')
    user.save()
    return user

Edit1:根据 cmets 中 bdbd 的建议,我在 CreateUserSeriailzer 中将 user 替换为 userdetails,它解决了 属性错误,但在创建用户时出现错误:

(1062, "重复的条目 '106' 用于键 'apis_userdetails.user_id'")

所以我替换了UserDetails.objects.create(user=user,**user_data) user.userdetails.phone=user_data.get('phone') user.userdetails.address=user_data.get('address')

如果有人知道如何进一步最小化此代码,请告诉我,因为我需要在 UserDetails 表中创建很多列,所以我不想手动在每列中添加每个值

更新了 Serializer.py(第一个)

class CreateUserSerializer(serializers.ModelSerializer):
    #user=UserDetailsSerializer()
    userdetails=UserDetailsSerializer()
    class Meta:
        model =User
        fields=['id','url','username','email','password','userdetails']

    def create(self, validated_data):
        user_data=validated_data.pop('userdetails')
        user=User.objects.create_user(**validated_data)
        # UserDetails.objects.create(user=user,**user_data)
        user.userdetails.phone=user_data.get('phone')
        user.userdetails.address=user_data.get('address')
        user.save()
        return user

【问题讨论】:

  • 在您的第一个序列化程序实现中,将user=UserDetailsSerializer() 更改为userdetails = UserDetailsSerializer()UserDetails 的相关名称来自User
  • 别担心!很高兴听到它起作用了
  • @bdbd 我更新了帖子,如果你知道如何进一步最小化它,请帮助我

标签: python django rest serialization django-rest-framework


【解决方案1】:

试试这个: 如果您选择不使用信号:

def create(self, validated_data):
    userdetails_data = validated_data.pop('userdetails')
    user = User.objects.create_user(**validated_data)
    UserDetails.objects.create(user=user, **userdetails_data)
    return user

如果您选择使用信号:

def create(self, validated_data):
    user_data = validated_data.pop('userdetails')
    user = User.objects.create_user(**validated_data)
    user.userdetails.phone = user_data.get('phone')
    user.userdetails.address = user_data.get('address')
    user.userdetails.save()
    return user

【讨论】:

  • 已经尝试过了,给了我同样的错误 - (1062,“重复条目'114'键'apis_userdetails.user_id'”)。看到我的模型信号可能是问题所在?
  • 很可能是的。您是否在某个信号中创建UserDetails
  • 我添加了一个应该支持信号的答案。只需选择您需要的。
猜你喜欢
  • 2021-09-25
  • 1970-01-01
  • 1970-01-01
  • 2017-03-08
  • 1970-01-01
  • 2017-12-29
  • 1970-01-01
  • 2017-03-06
  • 1970-01-01
相关资源
最近更新 更多