路飞项目第五天

news/2024/11/25 4:12:08/

路飞项目第五天

  • 今天我们来做注册
    • 在index里引一下路径
      • 获取验证码按钮也做一下

今天我们来做注册

先在components文件夹下创建一个组件Register
在这里插入图片描述

Register代码

<template><div class="box"><img src="../../static/image/Loginbg.3377d0c.jpg" alt=""><div class="register"><div class="register_box"><div class="register-title">注册路飞学城</div><div class="inp"><input v-model = "mobile" type="text" placeholder="手机号码" class="user"><input v-model = "password" type="password" placeholder="登录密码" class="user"><input v-model = "sms_code" type="text" placeholder="输入验证码" class="user"><!-- <div id="geetest"></div>滑动验证这里我就不加了 --><button class="register_btn" >注册</button><p class="go_login" >已有账号 <router-link to="/user/login">直接登录</router-link></p></div></div></div></div>
</template><script>
export default {name: 'Register',data(){return {sms_code:"",mobile:"",password:"",validateResult:false,}},created(){},methods:{},};
</script><style scoped>
.box{width: 100%;height: 100%;position: relative;overflow: hidden;
}
.box img{width: 100%;min-height: 100%;
}
.box .register {position: absolute;width: 500px;height: 400px;top: 0;left: 0;margin: auto;right: 0;bottom: 0;top: -120px;
}
.register .register-title{width: 100%;font-size: 24px;text-align: center;padding-top: 30px;padding-bottom: 30px;color: #4a4a4a;letter-spacing: .39px;
}
.register-title img{width: 190px;height: auto;
}
.register-title p{font-family: PingFangSC-Regular;font-size: 18px;color: #fff;letter-spacing: .29px;padding-top: 10px;padding-bottom: 50px;
}
.register_box{width: 400px;height: auto;background: #fff;box-shadow: 0 2px 4px 0 rgba(0,0,0,.5);border-radius: 4px;margin: 0 auto;padding-bottom: 40px;
}
.register_box .title{font-size: 20px;color: #9b9b9b;letter-spacing: .32px;border-bottom: 1px solid #e6e6e6;display: flex;justify-content: space-around;padding: 50px 60px 0 60px;margin-bottom: 20px;cursor: pointer;
}
.register_box .title span:nth-of-type(1){color: #4a4a4a;border-bottom: 2px solid #84cc39;
}.inp{width: 350px;margin: 0 auto;
}
.inp input{border: 0;outline: 0;width: 100%;height: 45px;border-radius: 4px;border: 1px solid #d9d9d9;text-indent: 20px;font-size: 14px;background: #fff !important;
}
.inp input.user{margin-bottom: 16px;
}
.inp .rember{display: flex;justify-content: space-between;align-items: center;position: relative;margin-top: 10px;
}
.inp .rember p:first-of-type{font-size: 12px;color: #4a4a4a;letter-spacing: .19px;margin-left: 22px;display: -ms-flexbox;display: flex;-ms-flex-align: center;align-items: center;/*position: relative;*/
}
.inp .rember p:nth-of-type(2){font-size: 14px;color: #9b9b9b;letter-spacing: .19px;cursor: pointer;
}.inp .rember input{outline: 0;width: 30px;height: 45px;border-radius: 4px;border: 1px solid #d9d9d9;text-indent: 20px;font-size: 14px;background: #fff !important;
}.inp .rember p span{display: inline-block;font-size: 12px;width: 100px;/*position: absolute;*/
/*left: 20px;*/}
#geetest{margin-top: 20px;
}
.register_btn{width: 100%;height: 45px;background: #84cc39;border-radius: 5px;font-size: 16px;color: #fff;letter-spacing: .26px;margin-top: 30px;
}
.inp .go_login{text-align: center;font-size: 14px;color: #9b9b9b;letter-spacing: .26px;padding-top: 20px;
}
.inp .go_login span{color: #84cc39;cursor: pointer;
}
</style>

在index里引一下路径

在这里插入图片描述
在这里插入图片描述
Login.vue里设置一下路径
在这里插入图片描述
Register.vue也是
在这里插入图片描述

获取验证码按钮也做一下

去element-ui上找一些样式
在这里插入图片描述
在这里插入图片描述

相互嵌套一下
在这里插入图片描述
效果
在这里插入图片描述
接下来校验一下用户输入的手机号
前端先写个点击事件
在这里插入图片描述

在这里插入图片描述

后端先写一个路由
在这里插入图片描述
users/views代码

from django.shortcuts import render# Create your views here.from rest_framework_jwt.views import JSONWebTokenAPIView
from .serializers import CustomJSONWebTokenSerializer
from rest_framework.views import APIViewclass LoginView(JSONWebTokenAPIView):serializer_class = CustomJSONWebTokenSerializerimport re
from rest_framework.response import Response
from rest_framework import status
from .utils import get_user_by_account
class CheckPhoneView(APIView):def post(self,request):phone = request.data.get('phone')# 格式校验if not re.match('1\d{10}',phone):return Response({'error':'手机号码格式有误'},status=status.HTTP_400_BAD_REQUEST)# 校验手机号唯一性ret = get_user_by_account(phone)if ret:return Response({'error': '手机号已被注册'}, status=status.HTTP_400_BAD_REQUEST)return Response({'msg':'ok'})

看看效果
在这里插入图片描述
在这里插入图片描述
接下来后台要写注册逻辑
先写个路由
在这里插入图片描述
再写个视图,users/views代码

from django.shortcuts import render# Create your views here.from rest_framework_jwt.views import JSONWebTokenAPIView
from .serializers import CustomJSONWebTokenSerializer
from rest_framework.views import APIView
from . import modelsclass LoginView(JSONWebTokenAPIView):serializer_class = CustomJSONWebTokenSerializerimport re
from rest_framework.response import Response
from rest_framework import status
from .utils import get_user_by_account
class CheckPhoneView(APIView):def post(self,request):phone = request.data.get('phone')# 格式校验if not re.match('1\d{10}',phone):return Response({'error':'手机号码格式有误'},status=status.HTTP_400_BAD_REQUEST)# 校验手机号唯一性ret = get_user_by_account(phone)if ret:return Response({'error': '手机号已被注册'}, status=status.HTTP_400_BAD_REQUEST)return Response({'msg':'ok'})from rest_framework.generics import CreateAPIView
from .serializers import RegisterModelSerializer
class RegisterView(CreateAPIView):queryset = models.User.objects.all()serializer_class = RegisterModelSerializer

写个序列化器
users/serializers代码

from django.contrib.auth import authenticate, get_user_model
from django.utils.translation import ugettext as _
from rest_framework import serializers
from rest_framework_jwt.compat import Serializerfrom rest_framework_jwt.settings import api_settings
from rest_framework_jwt.compat import get_username_field, PasswordField
import re
from .utils import get_user_by_accountfrom django.contrib.auth.hashers import make_password
from .models import UserUser = get_user_model()
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
jwt_decode_handler = api_settings.JWT_DECODE_HANDLER
jwt_get_username_from_payload = api_settings.JWT_PAYLOAD_GET_USERNAME_HANDLERclass CustomJSONWebTokenSerializer(Serializer):def __init__(self, *args, **kwargs):"""Dynamically add the USERNAME_FIELD to self.fields."""super(CustomJSONWebTokenSerializer, self).__init__(*args, **kwargs)self.fields[self.username_field] = serializers.CharField()self.fields['password'] = PasswordField(write_only=True)self.fields['ticket'] = PasswordField(write_only=True)self.fields['randstr'] = PasswordField(write_only=True)@propertydef username_field(self):return get_username_field()def validate(self, attrs):credentials = {self.username_field: attrs.get(self.username_field),'password': attrs.get('password'),'ticket': attrs.get('ticket'),'randstr': attrs.get('randstr'),}if all(credentials.values()):user = authenticate(self.context['request'], **credentials)if user:if not user.is_active:msg = _('User account is disabled.')raise serializers.ValidationError(msg)payload = jwt_payload_handler(user)return {'token': jwt_encode_handler(payload),'user': user}else:msg = _('Unable to log in with provided credentials.')raise serializers.ValidationError(msg)else:msg = _('Must include "{username_field}" and "password".')msg = msg.format(username_field=self.username_field)raise serializers.ValidationError(msg)# 注册的序列化器
class RegisterModelSerializer(serializers.ModelSerializer):sms_code = serializers.CharField(max_length=6, min_length=4,write_only=True)token = serializers.CharField(max_length=256,read_only=True)class Meta:model = Userfields = ['id','username','phone','password','sms_code','token']extra_kwargs = {'password': {'write_only':True,},'phone': {'write_only': True,},'username':{'read_only': True,},'id':{'read_only': True,}}def validate_phone(self,phone):# 手机号格式校验if not re.match('1\d{10}', phone):raise serializers.ValidationError('手机号格式有误!')# 手机号唯一性校验ret = get_user_by_account(phone)if ret:raise serializers.ValidationError('手机号已经被注册啦!!')return phonedef create(self,validated_data):password = validated_data.get('password')hash_password = make_password(password)user = User.objects.create(**{'phone': validated_data.get('phone'),'password': hash_password,'username': validated_data.get('phone'),})from rest_framework_jwt.settings import api_settingsjwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLERjwt_encode_handler = api_settings.JWT_ENCODE_HANDLERpayload = jwt_payload_handler(user)token = jwt_encode_handler(payload)user.token = token # 给user对象赋属性return user

我们测试一下接口,发现没问题
在这里插入图片描述
数据都保存了,接下来该让它注册成功后跳转到首页
前端Register先写个方法
在这里插入图片描述
绑定一个点击事件
在这里插入图片描述
注册完账户自动登录跳转到首页了
在这里插入图片描述
手机号也注册进去了
在这里插入图片描述
接下来做一下真正的短信验证码
后台要生成验证码,所以我们先写一个接口
先写个路由
在这里插入图片描述
安装一下redis客户端django-redis

pip install django-redis

接下来去dev配置一下让django能连接我们的redis服务端

# 设置redis缓存
CACHES = {# 默认缓存"default": {"BACKEND": "django_redis.cache.RedisCache",# 项目上线时,需要调整这里的路径"LOCATION": "redis://127.0.0.1:6379/0", "OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient",}},# 提供给xadmin或者admin的session存储"session": {"BACKEND": "django_redis.cache.RedisCache","LOCATION": "redis://127.0.0.1:6379/1","OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient",}},# 提供存储短信验证码"sms_code":{"BACKEND": "django_redis.cache.RedisCache","LOCATION": "redis://127.0.0.1:6379/2","OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient",}}
}# 设置xadmin用户登录时,登录信息session保存到redis
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "session"

http://www.ppmy.cn/news/503183.html

相关文章

路飞项目整体流程(二)

文章目录 一、配置之封装Logger二、配置之封装全局异常三、后台配置之二次封装Response四、数据库配置五、User模块User表配置六、开放Media访问七、路飞前端项目创建配置1&#xff09;安装Axios2&#xff09;安装Elementui3&#xff09;安装Vue-cookies 一、配置之封装Logger …

路飞day3

1 前台全局样式和js配置 body div 默认样式&#xff0c;统一去掉 css.global /* 声明全局样式和项目的初始化样式 */ body, h1, h2, h3, h4, h5, h6, p, table, tr, td, ul, li, a, form, input, select, option, textarea {margin: 0;padding: 0;font-size: 15px; }a {text-…

路飞项目day1

1 企业项目开发流程 开发流程 -立项 -需求分析 # 互联网项目 -需求调研和分析&#xff1a;产品经理设计出来的 # 传统软件 -需求调研和分析&#xff1a;市场人员跟客户对接 -原型设计&#xff1a;产品经理 -懂业务 -分任务开发 -前端团队 -UI设计 -前端写代码&#xff08;pc&am…

路飞day2

0 .环境变量补充 1 相对导入和绝对导入 -相对导入必须从环境变量下开始导 sys.path -如果报包找不到的错&#xff0c;确认环境变量 -绝对导入&#xff0c;以当前文件为基准导入 -它不能以脚本形式运行&#xff0c;只能当包用 2 导入包&#xff0c;pycharm提示错误&#xff…

使用Kettle做数据迁移

1.Kettle简介 Kettle是一个颇受认可的开源ETL(Extract-Transform-Load 的缩写&#xff0c;即数据抽取、转换、装载的过程)工具&#xff0c;2006年被Pentaho收购&#xff0c;2015年又被Hitachi Vantara收购&#xff0c;正式命名为PDI。 PDI EE&#xff08;企业商用版&#xff0…

某网页在线视频有声音无图像

1.某网页在线视频打开有声音无图像&#xff0c;使用谷歌浏览器&#xff0c;360浏览器&#xff08;极速模式&#xff09;都是一样&#xff0c;检查后关闭谷歌浏览器“使用硬件加速模式”&#xff0c;360浏览器“智能开启硬件加速”。重启浏览器就可以正常观看。不过这类问题不一…

网页在线视频只有声音没有图像

Windows Media Player-->Tools-->Performance-->Video acceleration 设置为"None"。