JAVA网络爬虫
HttpClient

导航

 

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"
            )
    
    
posted on 2019-09-19 21:39  gmlgxx  阅读(246)  评论(0)    收藏  举报