一、前端首页中间部分样式
<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。