前言:
上篇博客我们已经对设置了图形验证码,短信验证码对用户信息进行了一些简单的验证,本篇博客我们会将上篇的一些验证方法进行结合,来进一步完成我们的注册工作
1. 创建视图类
在user中的view创建CreateUserAPIView类,而且这个类继承自APIView(一级视图)
class CreateUserAPIView(APIView):
def post(self,request):
# 注意该类继承自APIView,获取post数据要用request.data
data = request.data
# 创建序列化器
serializers = CreateUserAPIViewSerializers(data=data)
serializers.is_valid(raise_exception=True)
# 注意data中含有password2等User模型类中并没有的字段,需要在差un关键对象之前将这些字段删除
# 因此需要重写create方法
serializers.save()
# 返回响应
return Response(serializers.data)
2.创建序列化器CreateUserAPIViewSerializers
lass CreateUserAPIViewSerializers(serializers.ModelSerializer):
"""
由于User类中没有 password2 sms_code,allow信息,因此无法自动生成该序列化字段,需要手动创建
"""
password2 = serializers.CharField(max_length=20,min_length=5,write_only=True,label="确认密码")
sms_code = serializers.CharField(max_length=6,min_length=6,write_only=True,label="短信验证码")
allow = serializers.CharField(label="是否同意用户协议",allow_blank=False,write_only=True)
token = serializers.CharField(label='登录状态token', read_only=True) # 增加token字段
class Meta:
model = User
fields = ('id','username','password','password2','mobile','sms_code','allow','token','email_active')
extra_kwargs = {
'id': {'read_only': True},
'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 validated_mobile(self,mobile):
if re.match(r'1[345789]\d{9}',mobile):
raise serializers.ValidationError('电话格式错误!')
return mobile
def validated_allow(self,allow):
if allow != 'True':
raise serializers.ValidationError("请勾选协议!")
# 多个字段验证
def validate(self, attrs):
mobile = attrs.get('mobile') # 用户输入的电话
sms_code = attrs.get('sms_code') # 用户输入的短信验证码
password = attrs.get('password') # 第一次输入的密码
password2 = attrs.get('password2') # 第二次输入的密码
if password != password2:
raise serializers.ValidationError("两次输入的密码不一致!")
# 获取redis中的验证码
sms_redis = get_redis_connection('smscode')
smscode = sms_redis.get('sms_%s'%mobile) # redis中存储的验证码
if smscode is None:
raise serializers.ValidationError('短信验证码已经过期!')
if smscode.decode() != sms_code:
raise serializers.ValidationError('短信验证码错误!')
return attrs
def create(self, validated_data):
del validated_data['password2']
del validated_data['sms_code']
del validated_data['allow']
user = User.objects.create(**validated_data)
#修改密码
user.set_password(validated_data['password'])
#注意保存
user.save()
# 补充生成记录登录状态的token
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
user.token = token
return user
上篇博客也提到了创建序列化器的两种方法,我会专门写一篇博客来详细的说明这两种方法
3. 将路由地址注册到urls
urlpatterns = [
......
url(r'^$',views.CreateUserAPIView.as_view()),
]
4. 验证
这时当你输入所有的信息之后点击注册时并没有任何的反应,我们打开浏览器的调试工具,如下图所示
服务器并没有响应200,而是响应了400,这是怎么回事呢?我发现我们请求之前的ip是127.0.0.1:8080,但我们却向127.0.0.1:8000请求数据,这就会引发跨域的问题,那么什么是跨域,跨域怎么解决呢?可以参考我之前的博客:https://www.cnblogs.com/xuchuankun/p/9780896.html
我们按照说明进行跨域配置之后,再来进行注册验证,结果我们就会发现我们的数据经过序列化器的校验后成功的存入数据库
数据库中的这条记录就是刚刚我们注册的数据,到此为止我们的注册功能就实现了。我们还可以根据需求进行适当的修改。希望能帮助大家,同时也感谢大家的查看