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" )