python之路81 路飞项目、为开源代码贡献代码、pycharm使用git、登录注册功能分析、手机号是否存在接口、多方式登录接口、腾讯云短信申请

为开源项目贡献代码

# github,gitee 看到好的开源项目,  发现有bug,为他增加新功能---》你加入了代码---》想合并进开源项目,如何做

# 步骤:
    1 先fork开源项目--》复制这个项目到我的仓库中
    2 clone下来,改代码,一路提交到远端(我的)
    3 提交pr,等作者同意

pycharm使用git

只要用命令操作的,都可以点击完成,只需要点点点

登录注册功能分析

接口分析
    5 校验手机号是否存在的接口
    1 多方式登录接口:用户名/手机号/邮箱 +密码都可以登录
    2 发送手机验证码接口   (接助于第三方短信平台) 
    3 短信登陆接口
    4 注册接口

手机号是否存在接口

url.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 .models import User
from utils.common_response import APIResponse


class UserView(GenericViewSet):
    @action(methods=['GET'], detail=False)  # 保证这个接口的安全(短信轰炸机==) 解析除了好多网站的发送短信接口,用多线程
    def send_sms(self, request, *args, **kwargs):
        try:
            # 从地址栏中取出手机号 query_params : queryDict
            mobile = request.query_params['mobile']
            User.objects.get(mobile=mobile)
        except Exception as e:
            raise e
        # return APIResponse(code=777,msg='手机号不存在')
        return APIResponse(msg='手机号存在')

视图函数模板

 def send_sms(self, request, *args, **kwargs):
        try:
            写视图代码 有异常抛出,然后封装的全局异常代码接收 
        except Exception as e:
            raise e
        return APIResponse()

多方式登录接口

使用 用户名,手机号,邮箱+密码登录

post--{username:3@qq.com,password:123}

视图类

from rest_framework.viewsets import GenericViewSet
from rest_framework.decorators import action
from .models import User
from utils.common_response import APIResponse
from rest_framework.viewsets import ViewSetMixin
from rest_framework.generics import GenericAPIView
from .serializer import UserLoginSerializer

class UserView(GenericViewSet):
# class UerView(ViewSetMixin,GenericAPIView)
    serializer_class = UserLoginSerializer
    queryset = User.objects.all().filter(is_active=True)
    @action(methods=['GET'], detail=False)  # 保证这个接口的安全(短信轰炸机==) 解析除了好多网站的发送短信接口,用多线程
    def send_sms(self, request, *args, **kwargs):
        try:
            # 从地址栏中取出手机号 query_params : queryDict
            mobile = request.query_params['mobile']
            User.objects.get(mobile=mobile)
        except Exception as e:
            raise e

        # return APIResponse(code=777,msg='手机号不存在')
        return APIResponse(msg='手机号存在')

    @action(methods=['POST'], detail=False)
    def login_mul(self, request, *args, **kwargs):
        '''
        把这个逻辑放在序列化类中
        1 取出前端传入的用户名和密码
        2 通过用户名和密码去数据库查询用户
        3 如果能查到,签发token
        4 返回给前端登录成功
        ...
        '''
        # 实例化 序列化类对象时,可以传入context字典 context是视图类和序列化类沟通的桥梁
        # 序列化类全局钩子,放入的
        # 有了序列化类对象,通过对象.context 就可以拿到值
        ser = self.get_serializer(data=request.data)
        ser.is_valid(raise_exception=True)  # 执行这句话,会走字段自己的校验,局部钩子,全局钩子
        token = ser.context.get('token')  # ser.context 是什么先不捉急
        username = ser.context.get('username')
        return APIResponse(token=token, username=username)  # {code:100,msg:成功,token:aaaa,usernmae:lqz}

路由 (在主路由中做过路由分发)

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

序列化类 主要用于校验字段

from .models import User
from rest_framework import serializers
import re
from rest_framework.exceptions import APIException,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 UserLoginSerializer(serializers.ModelSerializer):
    # 重写一下uername 把原来的校验规则去掉
    username = serializers.CharField()
    class Meta:
        model = User
        # username 映射过来,是唯一的,字段自己的校验就过不了 所以要重写这个字段
        fields = ['username','password']  # 这个序列化类用来校验字段==不做序列化,不做反序列化

    # 全局钩子
    def validate(self,attrs):
        '''
        把这个逻辑放在序列化类中
        1 取出前端传入的用户名和密码
        2 通过用户名和密码去数据库查询用户
        3 如果能查到,签发token
        4 返回给前端登录成功

        '''
        # attrs 是前端传入的数据,经过, 字段自己校验和局部钩子校验后的数据 {username:lqz,password:123}
        user = self._get_user(attrs)
        token = self._get_token(user)
        # 把用户名,和token放到user的context中
        self.context['token'] = token
        self.context['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()
        if user and user.check_password(password):
            return user
        else:
            # 用户不存在或密码错误, 这里的代码,还是在全局钩子中执行,全局钩子校验失败要抛异常,所以在这抛异常
            raise APIException('用户不存在或密码错误')
    def _get_token(self,user):
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        return token

腾讯云短信申请

发送短信接口,借助于第三方短信平台,收费的
     腾讯云短信
     阿里 大于短信
     。。。。

需要申请微信公众号:百度自己注册 需要实名认证

使用腾讯短信
     https://cloud.tencent.com,微信扫码登录
     搜索短信:https://console.cloud.tencent.com/smsv2
      创建短信签名:公众号注册,提交等待审核
     创建短信正文模版
     等待审核
     发送短信
        python 代码发送短信

 # API SDK
    API: 咱们学习过的API接口,写起来比较麻烦,自己分析接口
    
    SDK:集成开发工具包,分语言,java,python,go
        使用python 对api进行封装成包
        以后我们只需要,安装包,导入包,包名.发送短信,传入参数,就可以发送了
    

     只要官方提供sdk,优先用sdk
     pip install tencentcloud-sdk-python

posted @ 2023-03-03 18:32  缀月  阅读(57)  评论(0)    收藏  举报