东莞市盛裕绒艺玩具有限公司

东莞市盛裕绒艺玩具有限公司

ebet体验版

18802637557
新闻资讯
联系方式
全国服务热线: 18802637557

咨询热线:15248559829
联系人:蒋本华
地址:泉州市泉港区南埔柳厝村枫林坑78号

Django商城项目笔记No.8用户部分-注册接口实现

来源:ebet体验版   发布时间:2019-06-17   点击量:252

Django商城项目笔记No.8用户部分-注册接口实现

users的view.py中增加如下代码

class RegisterUserView(CreateAPIView): """ 用户注册视图 """ serializer_class = serializers.RegisterUserSerializer

在users中创建serializers.py

class RegisterUserSerializer(serializers.ModelSerializer): """用户注册序列化器""" password2 = serializers.CharField(label="确认密码", write_only=True) sms_code = serializers.CharField(label="短信验证码", write_only=True) allow = serializers.CharField(label="同意协议", write_only=True) class Meta: model = User fields = ("id", "username", "password", "password2", "sms_code", "mobile", "allow") extra_kwargs = { "username": { "min_length": 5, "max_length": 20, "error_messages": { "min_length": "仅允许5-20个字符的用户名", "max_length": "仅允许5-20个字符的用户名", } }, "password": { "write_only": True, "min_length": 8, "max_length": 20, "error_messages": { "min_length": "仅允许8-20个字符的密码", "max_length": "仅允许8-20个字符的密码", } } } def validate_mobile(self, value): """验证手机号""" if not re.match(r"^1[3-9]d{9}$", value): raise serializers.ValidationError("手机号格式错误") return value def validate_allow(self, value): """检查用户是否同意协议""" if value != "true": raise serializers.ValidationError("请同意用户协议") return value def validate(self, attrs): # 判断两次密码 if attrs["password"] != attrs["password2"]: raise serializers.ValidationError("输入的两次密码不一致") # 判断短信验证码 redis_conn = get_redis_connection("verify_codes") # 获取真实验证码 real_sms_code = redis_conn.get("sms_%s" % attrs["mobile"]) # 如果取出来是None,那么代表已经超时了 if real_sms_code is None: raise serializers.ValidationError("短信验证码无效") # 注意real_sms_code 从redis中取出来的是bytes类型,需要decode一下 if attrs["sms_code"] != real_sms_code.decode(): raise serializers.ValidationError("短信验证码错误") return attrs def create(self, validated_data): """重写保存方法,增加密码加密""" # 移除数据库模型类中不需要的属性 # 删除字典数据的两种方法是 # del 字典[key] 删除指定键值对,key不存在不会报错 # 字典.pop(key) 删除指定键值对,key不存在会报错 del validated_data["password2"] del validated_data["allow"] del validated_data["sms_code"] # user = User.objects.create(username=xxx, password=xxxx, mobile=xxxx) user = User.objects.create(**validated_data) # 将密码加密,然后保存 user.set_password(validated_data["password"]) user.save() return userView Code

fields = ("id", "username", "password", "password2", "sms_code", "mobile", "allow")

fields=(),括号里面需要输入序列化和反序列化过程中所用到的所有字段,如果是模型类中没有的字段,可以在上面指明字段的类型和限制

password2 = serializers.CharField(label="确认密码", write_only=True)sms_code = serializers.CharField(label="短信验证码", write_only=True)allow = serializers.CharField(label="同意协议", write_only=True)

write_only=True的意思是指在序列化的时候使用,序列化(从后端往前端传叫序列化),反序列化(从前端往后端传,保存到数据库中,叫反序列化)

 

extra_kwargs = { "username": { "min_length": 5, "max_length": 20, "error_messages": { "min_length": "仅允许5-20个字符的用户名", "max_length": "仅允许5-20个字符的用户名", } }, "password": { "write_only": True, "min_length": 8, "max_length": 20, "error_messages": { "min_length": "仅允许8-20个字符的密码", "max_length": "仅允许8-20个字符的密码", } }

extra_kwargs是对字段做限制。“error_messages”是如果不符合限制的规则,提示的信息

def validate_mobile(self, value): """验证手机号""" if not re.match(r"^1[3-9]d{9}$", value): raise serializers.ValidationError("手机号格式错误") return value

validate_字段名,是对一个字段做判断。自己写判断规则,如果不符合的话,就抛出异常,最后再return value

def validate(self, attrs): 这是对多个字段做判断,attrs是一个字典,可以通过attrs["字段名"]来获取字段的值

不符合的话,也是raise 抛出异常,最后再return attrs


 

 最后重写create方法,创建user

创建之前要把数据库模型类中不需要的字段从validated_data中删掉

# 移除数据库模型类中不需要的属性 # 删除字典数据的两种方法是 # del 字典[key] 删除指定键值对,key不存在不会报错 # 字典.pop(key) 删除指定键值对,key不存在会报错

这里使用del删除

del validated_data["password2"]del validated_data["allow"]del validated_data["sms_code"]

删除之后,validated_data字典中只剩下这几个"id", "username", "password", "mobile" 键值对  TODO?


 

为什么要重写create方法,

user = User.objects.create(username=xxx, password=xxxx, mobile=xxxx)

user = User.objects.create(**validated_data)  # **validated_data是拆包,拆成上面的形式

因为password字段,需要存入的是加密后的密码,如果直接create()然后save()的话,存入的密码是明文,所以要调用user.set_password(validated_data["password"])

加密密码之后再进行save保存,然后return user


设置路由

前端js代码

// 注册 on_submit: function(){ this.check_username(); this.check_pwd(); this.check_cpwd(); this.check_phone(); this.check_sms_code(); this.check_allow(); if(this.error_name == false && this.error_password == false && this.error_check_password == false && this.error_phone == false && this.error_sms_code == false && this.error_allow == false) { axios.post(this.host + "/users/", { username: this.username, password: this.password, password2: this.password2, mobile: this.mobile, sms_code: this.sms_code, allow: this.allow.toString() }, { responseType: "json" }) .then(response => { location.href = "/index.html"; }) .catch(error=> { if (error.response.status == 400) { if ("non_field_errors" in error.response.data) { this.error_sms_code_message = error.response.data.non_field_errors[0]; } else { this.error_sms_code_message = "数据有误"; } this.error_sms_code = true; } else { console.log(error.response.data); } }) } }View Code

测试结果,去数据库查看

注册接口到这里就完成了

 

相关产品

COPYRIGHTS©2017 ebet体验版 ALL RIGHTS RESERVED 备案号:252