luffy之多方式登入接口和手机号是否存在接口和腾讯云
一、前端首页中间部分样式
<div class="course"> <el-row> <el-col :span="6" v-for="(o, index) in 8" :key="o" class="course_detail"> <!-- :span意思就是一行总共24列 然后除以6 那么一行就会有4个 然后循环8次 这样就会有两行 一行四个 --> <el-card :body-style="{ padding: '0px' }"> <img src="https://tva1.sinaimg.cn/large/e6c9d24egy1h1g0zd133mj20l20a875i.jpg" class="image"> <!--按理说应该是从后端获取这个写课程的价格 简介... 但是现在我把这些写死了 就是一个图片--> <div style="padding: 14px;"> <span>推荐课程</span> <div class="bottom clearfix"> <time class="time">价格:999</time> <el-button type="text" class="button">查看详情</el-button> </div> </div> </el-card> </el-col> </el-row> </div> <img src="https://tva1.sinaimg.cn/large/e6c9d24egy1h1g112oiclj224l0u0jxl.jpg" alt="" width="100%" height="500px"> <style scoped> .time { font-size: 13px; color: #999; } .bottom { margin-top: 13px; line-height: 12px; } .button { padding: 0; float: right; } .image { width: 100%; display: block; } .clearfix:before, .clearfix:after { display: table; content: ""; } .clearfix:after { clear: both } .course_detail { padding: 50px; } </style>
二、多方式登入接口
# 登入注册 1 多方式登入接口 eg: 可以是(用户名,手机号,邮箱 和密码登入) 2 校验手机号是否存在接口 3 发送验证码接口 4 验证码登入接口 5 手机号注册接口 # 我们先写多方式登入接口 前端会以 这样的样式传入后端 json格式 : {username:用户名/邮箱/手机号,password:123} --->post请求 我们之前写的逻辑判断都是在视图类中写方法 那么我现在可以直接在序列化类中写方法
2.1 视图类
# post--->查询--->自动生成路由,action装饰器可以在视图类中写多个函数 from rest_framework.viewsets import ViewSet, GenericViewSet, ViewSetMixin from rest_framework.decorators import action from .models import UserInfo from .serializer import UserMulLoginSerializer from utils.response import APIResponse class UserView(ViewSet): @action(methods=['POST'], detail=False) def mul_login(self, request): # 1 老写法 # username=request.data.get('username') # password=request.data.get('password') # 查询用户, # UserInfo.objects.filter(username=username,password=password) # 签发token # 返回 # 2 新写法:使用序列化类 ser = UserMulLoginSerializer(data=request.data) # 将前端获取到的数据给序列化类进行校验 # jwt 模块的登录就是这么写的 ser.is_valid(raise_exception=True) # 只要执行到这 就会执行:序列化类字段自己的校验规则,局部钩子,全局钩子 # 用户名密码校验通过了,在序列化类中--》签发token token = ser.context.get('token') username = ser.context.get('username') icon = ser.context.get('icon') # icon是个对象 字符串 return APIResponse(token=token, username=username, icon=icon) # 前端看到的样子{code:100,msg:成功,token:adsfa,username:root,icon:http://adsfasd.png}
2.2 序列化类
from rest_framework import serializers from .models import UserInfo import re from django.contrib.auth import authenticate from rest_framework.exceptions import ValidationError from rest_framework_jwt.settings import api_settings jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER # 这个序列类,只用来做登录校验,不做序列化,不做反序列化 class UserMulLoginSerializer(serializers.ModelSerializer): username = serializers.CharField() # 重写,优先用 现在的,就没有unique的限制了 class Meta: model = UserInfo fields = ['username', 'password'] # 封装之隐藏属性 __表示隐藏, _并不是隐藏,公司里约定俗成用 _ 表示只在内部用,如果外部想用,也可以用 def _get_user(self, attrs): # attrs 是校验过后的数据:字段自己的规则【字段自己有规则:坑】和局部钩子 username = attrs.get('username') # 因为我们写的UserInfo表继承的是内置User表 而该表写的username字段会有一个unique唯一约束 所以每次校验该字段的时候只要是注册过的 那么表中都会有该姓名 那么现在只要查到 都会触发这个唯一约束条件 都会直接报错 那么就不会执行下面的代码 # 所以我们需要重写username字段 然后取消掉unique唯一约束 password = attrs.get('password') # username可能是用户名,邮箱,手机号---》使用正则判断 if re.match(r'^1[3-9][0-9]{9}$', username): user = authenticate(mobile=username, password=password) elif re.match(r'^.+@.+$', username): # adsa@adsf 会有bug,用户名中如果有@,登录不了了 user = authenticate(email=username, password=password) else: user = authenticate(username=username, password=password) if user: return user else: raise ValidationError('用户名或密码错误') def _get_token(self, user): try: payload = jwt_payload_handler(user) token = jwt_encode_handler(payload) return token except Exception as e: raise ValidationError(str(e)) # 还要写别的 def validate(self, attrs): # 1 取出用户名和密码,校验用户是否存在 user = self._get_user(attrs) # 2 签发token token = self._get_token(user) # 3 把token放到序列化类对象中 self.context['token'] = token self.context['username'] = user.username self.context['icon'] = 'http://127.0.0.1:8000/media/'+str(user.icon) # 这是个对象,可能会有问题 # self.context['icon'] = user.icon # 这是个对象,可能会有问题 # 以后如果有问题,都抛异常 # 如没有问题,返回attrs return attrs
2.3 路由
from django.contrib import admin from django.urls import path, re_path from home import views from django.views.static import serve from django.conf import settings from . import views from rest_framework.routers import SimpleRouter router = SimpleRouter() # 127.0.0.1:8080/api/v1/userinfo/user/mul_login router.register('user', views.UserView, 'user') urlpatterns = [ ] urlpatterns += router.urls
三、验证手机号是否存在
# 我们验证手机号只需要把手机号放在地址后面即可 也是写在user的app中 # get请求: 127.0.0.1:8080/api/v1/userinfo/user/mobile/?mobile=132222222
3.1 视图类
class UserView(ViewSet): @action(methods=['GET'], detail=False) def mobile(self, request): try: mobile = request.query_params.get('mobile') UserInfo.objects.get(mobile=mobile) # 有且只有一个才不报错, return APIResponse(msg='手机号存在') # {code:100,msg:手机号存在} except Exception as e: raise APIException('手机号不存在') # {code:999,msg:手机号不存在}
四、腾讯云短信介绍和申请
# 我们写发送短信的需求 需要借助与第三方 第三方有很多 我们借助了腾讯云 # 腾讯云有许多服务 我们只需要使用短信即可 首先我们需要注册 然后搜索短信 https://console.cloud.tencent.com/smsv2
4.1 申请短信
# 申请使用腾讯云短信: 1 创建签名:使用公众号申请 -网站:备案:工信部备案 -申请个人一个公众号: -https://mp.weixin.qq.com/ -等审核通过 2 申请模板:发送短信的模板 {1} {2} 后期用代码填上 3 免费赠送100条 4 代码发送短信:参照文档写代码:https://cloud.tencent.com/document/product/382/13444 -v2 老一些 -v3 最新
4.2 什么是api什么是sdk
# API文档 -之前学的接口文档的概念 -使用api调用,比较麻烦,固定输入,接受固定的返回 -使用postman都可以测试,携带你的认证的秘钥。 # SDK:Software Development Kit 软件开发工具包 -分语言的 -基于API,使用某个编程语言封装的包 -例如python:pip install 包 -包.发短信(参数) -一般厂商都会提供各大主流语言的sdk # 腾讯短信sdk使用步骤 1 已开通短信服务,创建签名和模板并通过审核 # 开了 2 如需发送国内短信,需要先 购买国内短信套餐包。 #赠送了 3 已准备依赖环境:Python 2.7 - 3.6 版本。 #我们有 4 已在访问管理控制台 >API密钥管理页面获取 SecretID 和 SecretKey。 SecretID 用于标识 API 调用者的身份。 SecretKey 用于加密签名字符串和服务器端验证签名字符串的密钥,SecretKey 需妥善保管 5 短信的调用地址为sms.tencentcloudapi.com。