AttributeError: Got AttributeError when attempting to get a value for field code on serializer UserR

AttributeError: Got AttributeError when attempting to get a value for field code on serializer UserRegSerializer.The serializer field might be named incorrectly and not match any attribute or key on the UserProfile instance.Original exception text was: ‘UserProfile’ object has no attribute ‘code’.[19/Sep/2019 20:21:44] “POST /users/ HTTP/1.1” 500 119900

  • 报错图
    在这里插入图片描述

  • serializer他会拿code做序列化然而code被我们给delete掉了—解决方案在code加上write_only=True

    class UserRegSerializer(serializers.ModelSerializer):
        # 因为UserProfile里面没有code字段, 所以我们要加个code字段
        # help_text = "验证码" 提示是验证码
        # label 一个简短的文本字符串,可用作HTML表单字段或其他描述性元素中字段的名称。
        # write_only 将其设置True为确保在更新或创建实例时可以使用该字段,但在序列化表示时不包括该字段。 默认为 False
        code = serializers.CharField(required=True, write_only=True, max_length=4, min_length=4, label="验证码",
                                     error_messages={
                                         # 设置每种错误的错误提示
                                         # blank是指为空
                                         "blank": "请输入验证码",
                                         # required是键都没有才会报这个错误
                                         "required": "请输入验证码",
                                         "max_length": "验证码过长",
                                         "min_length": "验证码过短"
                                     },
                                     help_text="验证码")
    
        # allow_blank=False表示不能为空
        username = serializers.CharField(required=True, allow_blank=False, label="用户名",
                                         validators=[UniqueValidator(queryset=UserProfile.objects.all(), message="用户已经存在")])
    
        # 这里的style把密码设置为密文的, 就像input标签type属性设置为password一样
        # write_only 将其设置True为确保在更新或创建实例时可以使用该字段,但在序列化表示时不包括该字段。 默认为 False
        password = serializers.CharField(
            style={'input_type': 'password'}, label="密码", write_only=True,
        )
    
        def validate_code(self, code):
            """
            校验验证码
            :param code: 验证码
            :return: 验证码
            """
    
            # 在ModelSerializer前端传递过来的值都会放在initial_data里
    
            # 校验验证码是否存在, 这里一定要排序, 这样才能获取最后的那条记录 这里的username就是mobile
            verify_records = VerifyCode.objects.filter(code=code, mobile=self.initial_data["username"]).order_by("-add_time")
            if verify_records:
                # 获取到最后一条记录
                last_record = verify_records[0]
    
                # 校验验证码是否过期
                # 获取5分钟前的时间  验证码有效期为5分钟
                five_mintes_ago = datetime.now() - timedelta(hours=0, minutes=5, seconds=0)
    
                if five_mintes_ago > last_record.add_time:
                    raise serializers.ValidationError("验证码过期")
    
                if last_record.code != code:
                    raise serializers.ValidationError("验证码错误")
    
                # 因为code只做验证, 所以这里不用吧code return回来
            else:
                raise serializers.ValidationError("验证码错误")
    
        def validate(self, attrs):
            """
            校验所有的字段
            :param attrs:  attrs是所有字段组成的字典
            :return: attrs
            """
            # 因为mobile值就是username的值, 所以我们把username的值赋值给mobile
            attrs["mobile"] = attrs["username"]
            # 因为我们不需要code字段了, 所以这里可以直接删除
            del attrs["code"]
            return attrs
    
        class Meta:
            model = UserProfile
            # username必填, 因为UserProfile继承了AbstractUser
            # 模型类写了必填, 你序列化的字段写了这个字段的话, 那么前端必须传这个字段的数据
            fields = (
                "username",
                "code",
                "mobile",
                "password"
            )
    
    
根据错误消息,问题出现在名为`phone`的字段上,该字段在`UserMySerializer`序列化器中。错误提示指出 `'AnonymousUser' object has no attribute 'phone'`,即`AnonymousUser`对象没有`phone`属性。 这个错误通常表示在你的代码中,你正在尝试使用一个匿名用户(即未经身份验证的用户)来访问一个需要`phone`属性的地方。匿名用户没有这个属性,因此会引发该错误。 要解决这个问题,你可以采取以下步骤: 1. 确保用户已经登录并且身份验证成功。你可以在处理请求的视图函数或类中使用适当的身份验证类或装饰器来验证用户身份。 2. 检查你的代码中是否有地方在未经身份验证的情况下尝试访问`phone`属性。确认在访问该属性之前进行了适当的身份验证。 3. 如果你希望在匿名用户的情况下允许访问该属性,你可以在序列化器中对该字段进行特殊处理。例如,你可以使用`SerializerMethodField`来定义一个自定义方法来返回匿名用户的默认值。 以下是一个示例代码片段来解决这个问题: ```python from rest_framework import serializers class UserMySerializer(serializers.ModelSerializer): phone = serializers.SerializerMethodField() def get_phone(self, obj): if self.context['request'].user.is_anonymous: return 'N/A' # 或者返回你希望的默认值 return obj.phone class Meta: model = User fields = ['phone', ...] # 其他字段 ``` 在上面的代码中,我们在`UserMySerializer`中使用了`SerializerMethodField`来定义一个名为`phone`的字段,并在`get_phone`方法中进行了特殊处理。如果请求的用户是匿名用户,我们返回一个默认值(例如"N/A"),否则返回用户对象的实际`phone`属性值。 通过这种方式,你可以确保在匿名用户的情况下不会引发该错误,并在需要时提供适当的默认值。记得根据你的具体需求进行适当的调整。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

只因为你温柔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值