drf---腾讯云短信发送组件(基于v2版本)

1. 腾讯云短信的注册

大佬的腾讯云短信注册攻略,亲测有用,NBhttps://pythonav.com/wiki/detail/10/81/

2. settings

2.1 安装django-redis

pip3 install django-redis -i https://pypi.douban.com/simple/

2.2 settings配置

# 腾讯云短信
TENCENT_SMS_APPID = xx  # 自己应用ID
TENCENT_SMS_APPKEY = "xxxxxxxxxxb27c594587c280"  # 自己应用Key
TENCENT_SMS_SIGN = "python后端接口开发"  # 签名管理里面的 自己腾讯云创建签名时填写的签名内容(使用公众号的话这个值一般是公众号全称或简称)
# 模板
TENCENT_SMS_TEMPLATES = {
    'register': 993292,
    'login': 993155
}

# redis
# 上面是django项目settings中的其他配置....
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://10.211.55.28:xxx",  # 安装redis的主机的 IP 和 端口
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS": {
                "max_connections": 1000,
                "encoding": 'utf-8'
            },
            "PASSWORD": "foobared"  # redis密码
        }
    },
    # 提供存储短信验证码
    "sms_code": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://106.14.42.253:xxx/2",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS": {
                "max_connections": 1000,
                "encoding": 'utf-8'
            },
            "PASSWORD": "foobared"  # redis密码
        }
    },
}

3. url

 # 手机短信码发送
    path('sms/code/', views.SmsCodeAPIView.as_view()),

4. view

from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response

from .serislizer import SmsCodeSerializer


class SmsCodeAPIView(APIView):
    """
    发送短信
    """
    def post(self, request, *args, **kwargs):
        smm_ser_obj = SmsCodeSerializer(data=request.data)
        if smm_ser_obj.is_valid():
            return Response({'status': 200, "msg": "ok", "data": ""}, status=status.HTTP_200_OK)
        return Response({'status': 400, "msg": smm_ser_obj.errors, "data": ""}, status=status.HTTP_400_BAD_REQUEST)

5. serializer

import random
from rest_framework import serializers
from django.conf import settings

from .utils import check_phone

from utils.centent.sms import send_sms_single
from django_redis import get_redis_connection


class SmsCodeSerializer(serializers.Serializer):
    """短信发送序列化器"""
    phone = serializers.CharField(max_length=11, min_length=11, write_only=True)
    tpl = serializers.CharField()

    def validate(self, validate_data):
        phone = validate_data.get('phone')
        # 进行短信模板id校验
        tpl = validate_data.get('tpl')
        # tpl
        tpl_id = self._get_tpl_id(tpl=tpl)
        # 进行手机号格式校验
        ret = check_phone(phone=phone)
        if ret:
            code = self._set_code(phone=phone)
            # 都通过发验证码
            self._send_sms(phone=phone, tpl_id=tpl_id, code=code)
            return validate_data
        raise serializers.ValidationError('手机号验证失败')

    def _get_tpl_id(self, tpl):
        """
        短信模板id的获取
        :param tpl: 前端传过来的,login/register/...
        :return:
        """
        if not tpl:
            raise serializers.ValidationError('模板缺失')
        tpl_id = settings.TENCENT_SMS_TEMPLATES.get(tpl)
        if not tpl_id:
            raise serializers.ValidationError('模板错误')
        return tpl_id

    def _set_code(self, phone):
        """
        生成验证码存放redis
        :param phone: 手机号
        :return:
        """
        # 生成code
        code = random.randrange(1000, 9999)
        print(code)
        # 保存redis
        conn = get_redis_connection('sms_code')
        pipe = conn.pipeline()  # 创建管道
        pipe.multi()  # 开启批量操作  (事务,)
        #  # 后端倒计时校验 查看redis是否有,有抛异常
        init_code = conn.get('init_code_%s' % phone)
        if init_code:
            raise serializers.ValidationError('一分钟只能发一次')
        # 保存正常验证码
        pipe.set('sms_code_%s' % phone, code, ex=60 * 5)
        # 保存倒计时码
        pipe.set('init_code_%s' % phone, code, ex=60)
        pipe.execute()  # 批量执行了
        return code

    def _send_sms(self, phone, tpl_id, code):
        """
        celery 异步消息队列发送短信
        :param phone: 手机号
        :param tpl_id: tpl_id 前端传,根据settings里面配置的
        :param code: 验证码
        :return:
        """
        # todo celery异步消息队列
        send_sms_single(phone, tpl_id, [code, ])

6. sms(根路径/utils/centent/sms)

# -*- coding:utf-8 -*-

# 腾讯发生短信模块

# pip3 install qcloudsms_py

import ssl
# ssl._create_default_https_context = ssl._create_unverified_context
from qcloudsms_py import SmsMultiSender, SmsSingleSender
from qcloudsms_py.httpclient import HTTPError
from django.conf import settings


def send_sms_single(phone_num, template_id, template_param_list):
    """
    单条发送短信
    :param phone_num: 手机号
    :param template_id: 腾讯云短信模板ID
    :param template_param_list: 短信模板所需参数列表,例如:【验证码:{1},描述:{2}】,则传递参数 [888,666]按顺序去格式化模板
    :return:
    """
    appid = settings.TENCENT_SMS_APPID  # 自己应用ID
    appkey = settings.TENCENT_SMS_APPKEY  # 自己应用Key
    sms_sign = settings.TENCENT_SMS_SIGN  # 签名管理里面的 自己腾讯云创建签名时填写的签名内容(使用公众号的话这个值一般是公众号全称或简称)
    sender = SmsSingleSender(appid, appkey)
    try:
        response = sender.send_with_param(86, phone_num, template_id, template_param_list, sign=sms_sign)
    except HTTPError as e:
        response = {'result': 1000, 'errmsg': "网络异常发送失败"}
    return response  # 调用

7. utils(app内自己封装的组件)

import re


def check_phone(phone):
    """
    手机号校验
    :param phone: 手机号
    :return: True/None
    """
    ret = re.match('^1[3-9][0-9]{9}$', phone)
    if ret:
        return True
    return

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

骑猪去兜风z1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值