1. 程式人生 > 實用技巧 >celery非同步傳送簡訊並註冊使用者資訊

celery非同步傳送簡訊並註冊使用者資訊

1.1在celery_task/mian.py中添加發送簡訊函式

# celery專案中的所有導包地址, 都是以CELERY_BASE_DIR為基準設定.
# 執行celery命令時, 也需要進入CELERY_BASE_DIR目錄執行.



# -*- coding: utf-8 -*-
import os
from celery import Celery
import sys
CELERY_BASE_DIR = os.path.dirname(os.path.abspath(__file__))


# 定義celery例項, 需要的引數, 1, 例項名, 2, 任務釋出位置, 3, 結果儲存位置
app = Celery('mycelery', broker='redis://127.0.0.1:6379/14', # 任務存放的地方 backend='redis://127.0.0.1:6379/15') # 結果存放的地方 @app.task def add(x, y): return x + y from libs.rl_sms import send_message @app.task(bind=True) def send_sms_code(self, mobile, datas): sys.path.insert(0, os.path.join(CELERY_BASE_DIR,
'../syl')) # 在方法中導包 try: # 用 res 接收發送結果, 成功是:0, 失敗是:-1 res = send_message(mobile, datas) except Exception as e: res = '-1' if res == '-1': # 如果傳送結果是 -1 就重試. self.retry(countdown=5, max_retries=3, exc=Exception('簡訊傳送失敗'))
celery_task/mian.py

1.2 在verifications/views.py中新增celery傳送簡訊試圖函式

from rest_framework.permissions import AllowAny
from rest_framework.views import APIView
from rest_framework.response import Response
import re
import random
from libs.rl_sms import send_message
import sys
import os


class SmsCodeView(APIView):
    """使用apiview的限流"""
    # 1. 所有人可以訪問
    permission_classes = (AllowAny,)

    def post(self, request, send_sms_code=None):
        # 1. 獲取引數
        phone = request.data.get('phone')  # 手機號
        image_code = request.data.get('image_code')  # 圖片驗證碼
        image_code_uuid = request.data.get('image_code_uuid')  # 前端生成的uuid

        # 2. 檢查引數
        if not all([phone, image_code, image_code_uuid]):
            return Response({"code": 999, "msg": "引數不全"})
        if not re.match(r'^1[3456789]\d{9}$', phone):
            return Response({"code": 999, "msg": "手機號碼不正確"})

        # 3. 檢查是否傳送
        redis_client = get_redis_connection('img_code')
        phone_exists = redis_client.get(phone)
        if phone_exists:
            return Response({"code": 999, "msg": "頻繁傳送, 請稍後再試"})

        # # 驗證圖形驗證碼
        redis_image_code = redis_client.get(image_code_uuid)  # bytes
        if redis_image_code:
        #     # bytes 轉成 string
            redis_image_code = redis_image_code.decode()
        #
        # # 比較使用者提供的圖片內容是否和redis中儲存的一致
        if image_code.upper() != redis_image_code:
            return Response({'code': 999, 'msg': '圖片驗證碼不22正確'})

        # 4. 傳送
        code = '%06d' % random.randint(0, 999999)  # 隨機6位驗證碼

        from syl.settings import BASE_DIR
        sys.path.insert(0, os.path.join(BASE_DIR, '../celery_task'))
        from celery_task.main import send_sms_code    # 必須這麼寫, 從main中導包
        send_sms_code(phone, (code, "5"))

        # # 5.1 儲存code 到 redis中
        # redis_client.setex(phone, 60 * 5, code)  # phone:code, 5分鐘有效期
        # # 5.2 從redis中刪除這個圖片驗證碼, 以防再次被使用
        # redis_client.delete(image_code_uuid)

        # 5.3.使用 pipeline 批量操作
        pl = redis_client.pipeline()    # 例項化pipeline物件
        pl.setex(phone, 60 * 5, code)   # 儲存phone:code, 5分鐘有效期
        pl.delete(image_code_uuid)      # 從redis中刪除這個圖片驗證碼, 以防再次被使用
        pl.execute()

        # 6. 返回結果
        return Response({"code": 0, "msg": "簡訊傳送成功"})
verifications/views.py

1.3新增路由

from django.urls import path
from . import views

urlpatterns = [
    # path('image_codes/', views.ImageCodeView.as_view()),
    path('sms_codes/', views.SmsCodeView.as_view()),
]

2配置手機號是否符合,並註冊

2.1判斷手機號是否符合user/urls.py

urlpatterns = [
    path('register/', views.RegisterView.as_view()),# 註冊檢視

    path('count/', views.RegCountView.as_view()),  # 查詢使用者名稱手機號使用量的檢視


]
user/urls.py

2.2判斷手機號是否符合要求和註冊user/views.py

import datetime
import random




from django.http import HttpResponse
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import viewsets
from rest_framework.authentication import BasicAuthentication, SessionAuthentication
from rest_framework.decorators import action
from rest_framework.filters import OrderingFilter
from rest_framework.permissions import AllowAny, IsAdminUser, IsAuthenticated, IsAuthenticatedOrReadOnly
from rest_framework.response import Response
from rest_framework.throttling import UserRateThrottle
from rest_framework.pagination import PageNumberPagination
from rest_framework.views import APIView
from rest_framework.permissions import BasePermission, SAFE_METHODS
from .models import User
from .serializers import UserSerializer, UserUnActiveSerializer, UserInfoSerializer


from rest_framework_jwt.authentication import JSONWebTokenAuthentication


from django_redis import get_redis_connection










# 註冊介面
class RegisterView(APIView):
    """
    使用者註冊, 許可權是: 匿名使用者可訪問
    """
    # 自定義許可權類
    permission_classes = (AllowAny,)

    def post(self, request):
        """
        接收使用者名稱,密碼,手機號和驗證碼, 前端校驗兩遍一致性, 註冊成功後返回成功, 然後使用者自行登入獲取token
        1. 使用者名稱
        2. 密碼
        3. 手機號
        4. 驗證碼
        :param request:
        :return:  {'code':0,'msg':'註冊成功'}
        code: "260361"
        password: "123123"
        phone: "13303479527"
        username: "liangxuepeng"
        """
        username = request.data.get('username')
        phone = request.data.get('phone')
        code = request.data.get('code')
        passwrod = request.data.get('password')
        print(username,passwrod,phone,code)
        print("*"*50)

        if all([username, passwrod, phone, code]):
            pass
        else:
            return Response({'code': 999, 'msg': '引數不全'})

        # rand_name = self.randomUsername()
        # 驗證手機驗證碼


        redis_client = get_redis_connection('img_code')
        # print(redis_client)
        # print("*" * 50)
        code_redis = redis_client.get(phone)
        print(code_redis)
        print(phone)
        print("%"*50)
        # print(code_redis)
        # print("*" * 50)
        # print(code)
        # print("*" * 50)
        if code_redis:
            code_redis = code_redis.decode()

        if not code == code_redis:
            return Response({'code': 999, 'msg': '111手機驗證碼錯誤'})

        user = User(username=username, phone=phone)
        user.set_password(passwrod)
        user.save()

        return Response({'code': 0, 'msg': '註冊成功'})






# 查詢使用者數量介面
class RegCountView(APIView):
    # 註冊時需要驗證的使用者名稱和手機號是否使用

    # 自定義許可權類
    permission_classes = (AllowAny,)

    def post(self, request):
        # 接收引數:  驗證的內容type: username/phone,  data: '使用者名稱' 或者 '手機號',
        datatype = request.data.get('type')
        # print(datatype)
        data = request.data.get('data')
        print(data)
        if not all([data, datatype]):
            return Response({'code': 999, 'msg': '引數不完整'})
        if datatype == 'username':


            count= User.objects.filter(username=data).count()
        if datatype == 'phone':
            count = User.objects.filter(phone=data).count()

        return Response({'code': 0, 'msg': '查詢成功', 'data': {'type': datatype, 'count':count}})
user/views.py

2.3接收手機號驗證碼及

註冊榮聯 *雲通訊賬號

syl/libs/rl_sms.py

from ronglian_sms_sdk import SmsSDK

accId = '8a216da874af5fff0175009949c119d7'
accToken = '3a65d8861d284a748f08f1a0084d257f'
appId = '8a216da874af5fff017500994aa619de'


def send_message(phone,datas):
    sdk = SmsSDK(accId, accToken, appId)
    tid = '1'
    # mobile = '18238693040'
    # datas = ('666666', '5')
    resp = sdk.sendMessage(tid,phone, datas)
    return resp
syl/libs/rl_sms.py

介面及引數

http://192.168.56.100:8888/verify/sms_codes/