路飞项目---day07(为开源项目贡献代码,pycharm使用git,登录注册功能分析,及手机号是否存在及登录接口,腾讯云短信申请)
昨日回顾
# GIt内容大回顾
# 1 版本管理软件 :git,svn
-代码合并
-代码版本管理
-协同开发,合并代码
# 2 git 跟 svn 区别
# 3 git 安装:相应平台软件,下载完成,一路下一步----》命令:git
# 4 git ,gitlab,gitee,github,bitbucket
# 5 git 工作流程
-工作区
-暂存区
-版本库
-远程仓库
# 6 git 常用命令
-git init 名字 # .git 隐藏
-git status
-git add
-git commit -m
-git reset --hard 版本号
-git log
-git reflog
-设置用户名(全局和局部)
git config --global user.name '用户名'
# 7 git 忽略文件
.gitignore
# 8 分支管理
-查看:git branch
-git branch dev
-git checkout dev
-git branch -d dev
-合并分支:git merge dev
# 9 远程仓库(gitee)
-远程:创建仓库,空仓库
-本地:
git init
git add
git commit
# 添加远程仓库
git remote add origin 地址(ssh/http)
# 删除远程仓库
git remote remove origin
# 查看远程仓库
git remote
git push origin master # 需要输入用户名密码
git pull origin master # 每次提交代码之前先拉
# 10 git clone 地址
-你是开发者,项目已经有了,你需要克隆下来
git clone 开源项目 # 没有任何阻碍
# 10 ssh操作远程仓库
-公钥私钥----》
-公钥配置在gitee上,以后使用ssh推送代码,就不需要验证
-git remote add origin 地址(ssh)
# 11 冲突(面试)
-多人在同一分支开发
-分支合并
# 12 线上分支合并
-提交pr
# 13 远程仓库回滚(忘掉)
# 记住的
git add
git commit -m
git pull origin dev
git push origin dev
今日内容
1 为开源项目贡献代码
# github,gitee 看到好的开源项目, 发现有bug,为他增加新功能---》你加入了代码---》想合并进开源项目,如何做
# 步骤:
1 先fork开源项目--》复制这个项目到我的远程仓库中
2 clone下来,改代码,一路提交到我的远程仓库中
3 提交pr,等作者同意
先fork开源项目,到我的远程仓库中
clone下来,改代码,一路提交到我的远程仓库中 提交pr,等作者同意
.
.
.
.
.
2 pycharm使用git
# 只要用命令操作的,都可以点击完成
2.1 先配置pycharm使用git
提交所有变化文件的操作
.
提交一个文件操作
.
确认操作,也是如果只点击文件,就是确认一个文件,
如果点击文件夹,就是确认文件下所有的变化
.
双击一下文件,就可以看到,版本变化,加个注释,点击确认
.
拉去最新代码与自己代码合并
.
本地仓库代码推远程仓库
.
点勾,可以直接跳过add 并且再点commit and push
就可以直接推到远程仓库去了
.
如果git的路径没有添加到环境变量,这里就需要
选择到 bin/git.exe 配置好git安装路径
.
.
右下角的分支操作按钮,点击想要切换到的分支,checkout ,就切换过去了
所有本地与远程的分支操作,都在左下角
.
.
新增 删除 修改 远程仓库地址的名字
.
代码的对比,能看到每次版本修改的地方
还可以让历史版本与当前版本作对比
.
查看用户提交的代码记录
.
.
使用pycharm快捷从git上克隆项目代码
.
.
.
3 登录注册功能分析
# 接口分析
5 校验手机号是否存在的接口
1 多方式登录接口:用户名/手机号/邮箱 +密码都可以登录
2 发送手机验证码接口 (借助于第三方短信平台)
3 短信登录接口
4 注册接口
.
.
.
.
.
4 手机号是否存在接口
urls.py 代码
from rest_framework.routers import SimpleRouter
from . import views
router = SimpleRouter()
# http://127.0.0.1:8000/api/v1/user/userinfo/send_sms/ get 发送短信
router.register('userinfo',views.UserView,'userinfo')
urlpatterns = [
]
urlpatterns += router.urls
.
.
.
views.py
# 老版的
from rest_framework.viewsets import GenericViewSet
from rest_framework.decorators import action
from luffy_api.apps.user.models import User
# 老版本代码,感觉老版方便
class UserView(GenericViewSet):
@action(methods=['GET'], detail=False)
def send_sms(self, request, *args, **kwargs):
# 从地址栏中取出手机号
mobile = request.query_params.get('mobile')
if mobile:
user_obj = User.objects.filter(mobile=mobile).first()
if user_obj:
return APIResponse(code=101, msg='手机号存在', exist=True)
else:
return APIResponse(code=101, msg='手机号不存在', exist=False)
else:
return APIResponse(code=999, msg='手机号必填')
------------------------------------------
------------------------------------------
# 新版的 利用全局异常处理
class UserView(GenericViewSet):
@action(methods=['GET'], detail=False)
def send_sms(self, request, *args, **kwargs):
try:
# 从地址栏中取出手机号 query_params :queryDict
mobile = request.query_params['mobile']
mobile = request.query_params.get('mobile')
User.objects.get(mobile=mobile)
except Exception as e:
raise e
# return APIResponse(code=777,msg='手机号不存在')
return APIResponse(msg='手机号存在')
# 保证这个接口的安全(短信轰炸机--》解析出了好多网站的发送短信接口,用多线程)
.
.
4.2 视图函数模版
def send_sms(self, request, *args, **kwargs):
try:
# 放心大胆写
except Exception as e:
raise e
return APIResponse()
.
.
.
.
.
.
.
5 多方式登录接口
# 可以任意使用 用户名,手机号,邮箱其中的一个 + 密码登录
# post--{username:用户名/手机号/邮箱,password:123}
# 由于用户输入的可能是用户名/手机号/邮箱,所以要先根据用户输入的值,
# 决定去User表里面是查用户名,还是手机号,还是邮箱
# 需要用正则去匹配一下
.
.
.
.
5.1 视图类
# 手机号是否存在接口
from rest_framework.viewsets import GenericViewSet
from rest_framework.decorators import action
from luffy_api.apps.user.models import User
from rest_framework.exceptions import APIException
# 老版本代码,校验手机号码是否存在,感觉老版方便
# class UserView(GenericViewSet):
#
# @action(methods=['GET'], detail=False)
# def send_sms(self, request, *args, **kwargs):
# # 从地址栏中取出手机号
# mobile = request.query_params.get('mobile')
# if mobile:
# user_obj = User.objects.filter(mobile=mobile).first()
# if user_obj:
# return APIResponse(code=101, msg='手机号存在', exist=True)
# else:
# return APIResponse(code=101, msg='手机号不存在', exist=False)
# else:
# return APIResponse(code=999, msg='手机号必填')
from luffy_api.apps.user.serializer import UserLoginSerializer
# 新版本的代码
class UserView(GenericViewSet):
serializer_class = UserLoginSerializer
queryset = User.objects.all().filter(is_active=True)
# 校验手机号是否存在
@action(methods=['GET'], detail=False)
def send_sms(self, request, *args, **kwargs):
# 从地址栏中取出手机号 query_params :queryDict
mobile = request.query_params.get('mobile')
if mobile:
# 有且只有一条,取不到会报错,变成django异常,会被全局捕获到
user_obj = User.objects.get(mobile=mobile)
return APIResponse(code=101, msg='手机号存在', exist=True)
else:
# 因为做了全局异常处理,所以主动抛异常也可以
# return APIResponse(code=999, msg='手机号必填')
raise APIException('手机号必填')
# 校验用户名与密码是否正确,如果正确返回token与用户名
@action(methods=['post'], detail=False)
def login_multiple(self, request, *args, **kwargs):
# 1 取出前端传入的用户名/手机号/邮箱 和密码
# 2 通过用户名和密码去数据库查询用户
# 3 如果能查到签发token
# 4 返回给前端 登录成功
ser = self.get_serializer(data=request.data)
ser.is_valid(raise_exception=True) # 走这句话,就会先执行字段自己的校验,然后局部钩子,全局钩子
# is_valid()方法里面,raise_exception参数默认是False,函数正常返回布尔值,
# 如果传raise_exception=True 校验过程发生异常后
# 被is_valid里面的try接收到后,还会被主动抛异常的代码把异常信息再抛出去,一旦主动抛异常了,下面的代码就不会再走了
# 在执行is_valid里面的全局钩子的时候,往ser.context对应的字典里面添加了数据
# 所以context是视图类与序列化类沟通的桥梁,先通过序列化的对象.context['xx']=yy
# 再在视图类函数里面,通过序列化的对象.context.get('xx') 拿到放进去的yy
token = ser.context.get('token')
username = ser.context.get('username')
return APIResponse(token=token, username=username)
# 代码不多,逻辑有点多,校验用户名与密码的逻辑放到了序列化类里面去了
.
.
.
.
5.2 序列化类
# 先下载jwt模块
pip install --index-url http://pypi.douban.com/simple/ djangorestframework-jwt --trusted-host pypi.douban.com
from luffy_api.apps.user.models import User
from rest_framework import serializers
import re
from rest_framework.exceptions import APIException
import rest_framework_jwt
from rest_framework_jwt.settings import api_settings
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
from django.db.models import Q
# 这个序列化类用来校验字段-------不用来序列化------也不用来做反序列化
class UserLoginSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['username', 'password']
# 由于从User模型表里映射过来的username字段有unique唯一的限制条件
# 所以序列化类里面该username字段校验,就也具有对唯一性的校验
# 当输入正确的用户名,走is_valid方法,经过序列化类字段自己的校验时,发现该用户名与数据里的用户名一样
# 就判断该用户名不具有唯一性,字段自己的校验就过不了,就直接抛异常了
# 所以要在序列化类里面重写username字段,把原来表模型里面的校验规则去掉!!!
username = serializers.CharField()
# 执行全局钩子函数
def validate(self, attrs):
# 1 取出前端传入的用户名/手机号/邮箱 和密码
# 2 通过用户名和密码去数据库查询用户
# 3 如果能查到签发token
# 4 返回给前端 登录成功
# attrs是前端传入的数据,经过字段自己校验,和局部钩子校验过后的数据
# 字段自己的校验是用fields将模型表对应的字段映射过来的,进行的校验
user = self._get_user(attrs)
token = self._get_token(user)
# 把用户名与token放到ser的context字典中去,方便在视图类里面,通过字典再拿到放进去的值!
self.context['token'] = token # context是序列化类的基类Field里面的方法伪装成属性,返回值是字典
self.context['username'] = user.username
# 此处也可以不用context方法,直接给对象赋值,
# 在视图类里直接通过 ser.token 拿对应的token值,但是该方法容易造成数据的污染,
# 因为假如序列化类里面又定义了一个变量叫token,就容易把该token的值给顶掉了
# self.token = token
# self.username = user.username
return attrs
def _get_user(self, attrs):
username = attrs.get('username')
password = attrs.get('password')
# 手机号的正则匹配
if re.match(r'^1[3-9][0-9]{9}$', username):
user = User.objects.filter(mobile=username).first()
# 邮箱的正则匹配
elif re.match(r'^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$', username):
user = User.objects.filter(email=username).first()
# 不是手机号与邮箱,默认是用户名了
else:
user = User.objects.filter(username=username).first()
# user = User.objects.filter(Q(username=username) | Q(email=username) | Q(mobile=username)).first()
# 上面的正则匹配也可以不用,直接用Q查询或的关系来解决
if user and user.check_password(password):
# 使用了auth_user表后具有的方法check_password
return user
else:
# 用户不存在或密码错误 这里的代码,还是在全局钩子中执行,全局钩子校验失败,要抛异常,所以在这抛异常
raise APIException('用户不存在或密码错误')
def _get_token(self, user):
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
# 这两行代码可以到jwt的源码里面的序列化类的文件里面去复制
return token
-----------------------------------------------------
.
.
.
.
.
.
.
.
.
.
6 腾讯云短信申请
# 发送短信接口,借助于第三方短信平台,收费的
-腾讯云短信
-阿里 大于短信
-。。。。
---------------------------------------
# 使用腾讯短信
https://cloud.tencent.com,微信扫码登录
先点产品,再在搜索框里面搜索短信,回车调到短信的页面
https://console.cloud.tencent.com/smsv2
1 创建短信签名:公众号注册,提交等待审核通过
2 需要先申请微信公众号,用网站或app认证比较烦
3 创建短信正文模版
-等待审核
-发送短信
python代码发送昂短信
------------------------------------------------
# API SDK
-API: 腾讯自己的API接口,我们要带着数据向对应的地址发送post请求,
然后腾讯会根据我们post携带的对应数据,发送对应的短信给对应的人
写起来比较麻烦,要自己分析腾讯的接口
------------------------------------------------
-SDK:集成开发工具包,分语言,java,python,go
-使用python 对api进行封装成包
-以后我们只需要,安装包,导入包,包名.发送短信,传入参数,就可以发送了
------------------------------------------------
-只要官方提供sdk,优先用sdk
先下载adk的模块
pip install tencentcloud-sdk-python
创建签名与模板,用了标准模板后,发现模板里面只能发6位以下的数字,很垃圾!
.
.
点过去
.
python sdk
.
安装python项目里面安装sdk模块
.
把发送短信的代码整体复制到,python文件里面去,对应参数改好,右键运行,就行了
.
需要改这5个参数
.
还要改的参数
.
.
要创一个应用,用sdk发送短信需要用到应用的id号
.
.
.
补充
# https://gitee.com/aeasringnar/django-RESTfulAPI/tree/master
# https://gitee.com/aeasringnar
.
.
.
作业
# 练习使用pycharm操作git
# 手机号是否存在
# 多方式登录接口
# 注册公众号
# 注册云短信,申请
# 使用python 测试发送短信
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY