为开源项目共享代码
步骤: 1先fork开源项目 2clone下来,修改代码,进行提交 3提交pr,等作者同意
Pycharm 使用Git
右键文件会列出Git命令
登录注册功能分析
多方式登录接口:用户名/手机号/邮箱 + 密码都可以登陆 发送手机验证码接口 (借助于第三方短信平台) 短信登录接口 注册接口
手机号是否存在接口
校验手机号是否存在
user/urls.py
路由层 from django.urls import path, include from rest_framework.routers import SimpleRouter from . import views router = SimpleRouter() router.register('user',views.UserView,'user') urlpatterns = [ path('',include(router.urls)) // ] # urlpatterns += router.urls
user/views.py
from rest_framework.viewsets import ViewSet from rest_framework.exceptions import APIException from rest_framework.decorators import action from utils.response import APIResponse from .models import UserInfo class UserView(ViewSet): @action(methods=['get'], detail=False) def check_mobile(self, request): try: # 如果布报错就说明手机号存在 mobile = request.query_params.get('mobile') UserInfo.objects.get(mobile=mobile) return APIResponse('手机号存在') except Exception as e: # raise e 也可以直接返抛出异常,就可以被全局异常捕获到 raise APIException('手机号不存在!')
视图函数模板
from restframework.response import APIresponse def send_sms(self, request, *args, **kwargs): try: # 放心大胆写 except Exception as e: raise e return APIResponse()
多方式登录接口
使用用户名/手机号/邮箱+密码登录
发送post请求到后端{"username":"xxx","password":"123"}
# 登录逻辑 1取出前端传入的用户名和密码 2通过用户名和密码去数据库查询 3查到了,签发token 4返回前端 将逻辑放入序列化类中..
视图类
- ser_obj.context >> 序列化类与视图类沟通的桥梁(本质上是个字典)
from rest_framework.viewsets import ViewSet from .serializer import UserMulLoginSerializer, MobileLoginSerializer from rest_framework.decorators import action from utils.response import APIResponse from .models import UserInfo class UserView(ViewSet): @action(methods=['post'], detail=False, ) def login(self, request): return self.common_login() def _get_serializer(self, data): # 因为我们有短信登录和多方式登录,可以将序列化类封装到函数中通过判断获取 # 判断请求方式返回不同的序列化类 res = self.request.META.get('PATH_INFO') # PATH_INFO 可以拿到请求的路径信息 if res == '/api/v1/userinfo/user/mobile_login/': return MobileLoginSerializer(data=data) return UserMulLoginSerializer(data=data) def common_login(self): ser_obj = self._get_serializer(data=self.request.data) # 执行这句话,会走字段自己的校验,局部钩子,全局钩子 ser_obj.is_valid(raise_exception=True) token = ser_obj.context.get('token') # 有了序列化类对象,通过 对象.context 就可以拿到值 icon = ser_obj.context.get('icon') username = ser_obj.context.get('username') return APIResponse(token=token, icon=icon, username=username)
序列化类
from rest_framework import serializers from .models import UserInfo from utils.common_serializer import Verification class UserMulLoginSerializer(serializers.ModelSerializer, Verification): # 全局钩子中有很多重复代码,我们直接将其封装到 (多方式登录和手机登录都可以使用) # utils目录下的common_serializer.py中 username = serializers.CharField() # 由于序列化类校验时会先走字段自己的校验,Mobile字段我们又设置了unique=True属性 # 所以如果我们请求来到了字段自己的校验就不会通过,我们需要重写该字段 class Meta: model = UserInfo fields = ['username', 'password'] def validate(self, attrs): attrs = self._validate(attrs) return attrs # 全局钩子必须返回校验后的数据 如果没有通过序列化类的校验,需抛出异常 我们又封装了全局捕获异常,所以就直接抛出即可
utils/common_serializer/Verification
import re from django.contrib.auth import authenticate from rest_framework.exceptions import ValidationError,APIException from django.core.cache import cache from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler from user.models import UserInfo class Verification(): def _get_token(self, user_obj): pay_load = jwt_payload_handler(user_obj) token = jwt_encode_handler(pay_load) return token def _validate(self,attrs): user_obj = self._get_user(attrs) token = self._get_token(user_obj) self.context['token'] = token # self 是 序列化类对象 所以可以点context传值进去 self.context['username'] = user_obj.username self.context['icon'] = 'http://127.0.0.1:8000/media/' + str(user_obj.icon) return attrs def _get_user(self, attrs): username = attrs.get('username') password = attrs.get('password') mobile = attrs.get('mobile') if mobile: if not re.match(r'^1[3-9][0-9]{9}$', mobile): raise ValidationError('手机号格式输入错误') code = attrs.get('code') old_code = cache.get('sms_code_%s' % mobile) if code == old_code: return UserInfo.objects.filter(mobile=mobile).first() raise APIException('验证码错误') if re.match(r'^1[3-9][0-9]{9}$', username): user_obj = UserInfo.objects.filter(mobile=username).first() if user_obj.check_password(password) and user_obj: return user_obj raise ValidationError('用户名或密码错误') # user_obj = authenticate(mobile=username, password=password) elif re.match(r'^.+@.+$', username): user_obj = authenticate(email=username, password=password) else: user_obj = authenticate(username=username, password=password) if not user_obj: raise ValidationError('用户名或密码错误') return user_obj
腾讯云短信申请
- 发送短信接口,借助于第三方短信平台
我们在使用云短信前需要自己申请Vx公众号(个人的即可)
- 使用腾讯短信
微信扫码登录
- 搜索短信:
- 创建短信签名:公众号注册,提交等待审核
- 创建短信正文模版
- 等待审核
- 发送短信(api接口 SDK)
API: 咱们学习过的API接口,写起来比较麻烦,自己分析接口,对上即可
SDK:集成开发工具包,分语言,java,python,go
使用python 对api进行封装成包
以后我们只需要,安装包,导入包,包名.发送短信,传入参数,就可以发送了
pip install tencentcloud-sdk-python