python学习之美多商城(四):用户部分--注册业务接口分析、跨域CORS、使用celery异步完成发送短信、

版权声明:浅弋、璃鱼的原创 https://blog.csdn.net/qq_35709559/article/details/84887789

一、注册:

创建好用户模型类后,我们开始来实现第一个业务逻辑——用户注册

1. 设计接口的思路:

  • 分析要实现的业务逻辑,明确在这个业务中需要涉及到几个相关子业务,将每个子业务当做一个接口来设计。

  • 分析接口的功能任务,明确接口的访问方式与返回数据:

    • 接口的请求方式,如GET 、POST 、PUT等
    • 接口的URL路径定义
    • 需要前端传递的数据及数据格式(如路径参数、查询字符串、请求体表单、JSON等)
    • 返回给前端的数据及数据格式
  • 特别强调:在前后端分离的应用模式中,我们作为后端开发人员设计后端接口时,可以不用考虑返回给前端数据后,前端如何处理,这是前端开发人员的工作,我们只需明确我们要保存的或者要返回的是什么数据即可。

明确上述每一点后,即可开始编写接口

2.注册业务接口分析:

在这里插入图片描述
在用户注册中,需要实现以下接口:

  • 短信验证码;
  • 用户名判断是否存在;
  • 手机号判断是否存在;
  • 注册保存用户数据;

二、短信验证码:

短信验证功能可以归属为第三方功能,所以创建一个新应用verifications,在此应用中实现短信验证码

1. 业务处理流程:

  • 1.生成和发送短信验证码;
  • 2.保存短信验证码;
  • 3.redis pipline的使用;
  • 4.检查是否在60s内有发送记录;
  • 5.celery异步发送短信;

2. 后端接口设计:

请求方式: GET /sms_codes/(?P<mobile>1[3-9]\d{9})/
请求参数: 路径参数

参数 类型 是否必须 说明
mobile str 手机号

返回数据:json

返回值 类型 是否必传 说明
message str OK,发送成功

3.后端实现:

class SMSCodeView(APIView):
    """发送短信验证码"""
    def get(self, request, mobile):
        """
        发送短信验证码
        url(r"^sms_codes/(?P<mobile>1[3-9]\d{9})/$", views.SMSCodeView.as_view()),
        :param request:
        :param mobile: 路径传参的手机号
        :return:
        """
        # 1.创建redis链接对象
        redis_conn = get_redis_connection("verify_codes")
        # 2.判断60秒内不允许重复发送短信
        send_flag = redis_conn.get("send_flag_%s" % mobile)
        if send_flag:
            return Response({"message":"发送短信过于频繁"}, status=status.HTTP_400_BAD_REQUEST)
        # 生成短信验证码
        sms_code = "%06d" % random.randint(0, 999999)

        # 发送短信: 调用第三方SDK
        CCP().send_template_sms(mobile,[sms_code, 300//60], 1)
        print("短信验证码:%s" % sms_code)
        # 使用redis管道pipeline缓存sms_code
        pl = redis_conn.pipeline()
        pl.setex("sms_code_%s" % mobile, 300//60, sms_code)
        pl.setex("send_flag_%s" % mobile, 300//60, 1)
        # 执行
        pl.execute()

        # 返回响应
        return Response({"message":"OK"})

但是,实现到这里,似乎一切都没有错,但是前端的请求却不能被后端接收,原因就是我们使用前后端分离的模式, 所以需要做跨域访问。

4.设置域名:

现在为前端和后端扥别设置两个不同的域名:

位置 域名
前端 www.meiduo.site
后端 api.meiduo.site

编辑*/etc/hosts*文件,可以设置本地域名

sudo nano /etc/hosts

在文件中增加两条信息:

127.0.0.1   api.meiduo.site
127.0.0.1   www.meiduo.site

windows系统中若设置本地域名,hosts文件在如下目录:
C:\Windows\System32\drivers\etc

我们在前端front_end_pc/js目录中,创建host.js文件用以为前端保存后端域名

var host = 'http://api.meiduo.site:8000';

在所有需要访问后端接口的前端页面中都引入host.js,使用host变量即可指代后端域名。

修改settings配置中的ALLOWED_HOSTS
一旦不再使用127.0.0.1访问Django后端,需要在配置文件中修改ALLOWED_HOSTS,增加可以访问后端的域名

ALLOWED_HOSTS = ['api.meiduo.site', '127.0.0.1', 'localhost', 'www.meiduo.site']

三、跨域CORS:

我们为前端和后端分别设置了两个不同的域名

位置 域名
前端 www.meiduo.site
后端 api.meiduo.site

现在,前端与后端分处不同的域名,我们需要为后端添加跨域访问的支持。
我们使用CORS来解决后端对跨域访问的支持。
使用django-cors-headers扩展

参考文档https://github.com/ottoyiu/django-cors-headers/

1. 安装:

pip install django-cors-headers

2. 添加到应用

INSTALLED_APPS = (
    ...
    'corsheaders',
    ...
)

3.中间件设置:

MIDDLEWARE = [
	# 跨域放在最上边
    'corsheaders.middleware.CorsMiddleware',
    ...
]

4.添加白名单:

# CORS
CORS_ORIGIN_WHITELIST = (
    '127.0.0.1:8080',
    'localhost:8080',
    'www.meiduo.site:8080',
    'api.meiduo.site:8000'
)
CORS_ALLOW_CREDENTIALS = True  # 允许携带cookie
  • 凡是出现在白名单中的域名,都可以访问后端接口
  • CORS_ALLOW_CREDENTIALS 指明在跨域访问中,后端是否支持对cookie的操作。

五、使用celery异步完成发送短信:

1. celery介绍:

在这里插入图片描述

2. celery的安装:

pip install celery

3.celery使用:

在meiduo/meiduo_mall下(manage同级)创建celery_tasks用于保存celery异步任务。

在celery_tasks目录下创建config.py文件,用于保存celery的配置信息。

broker_url = "redis://127.0.0.1/14"

在celery_tasks目录下创建main.py文件,用于作为celery的启动文件

from celery import Celery

# 为celery使用django配置文件进行设置
import os
if not os.getenv('DJANGO_SETTINGS_MODULE'):
    os.environ['DJANGO_SETTINGS_MODULE'] = 'meiduo_mall.settings.dev'

# 创建celery应用
app = Celery('meiduo')

# 导入celery配置
app.config_from_object('celery_tasks.config')

# 自动注册celery任务
app.autodiscover_tasks([
        'celery_tasks.sms',
                        ])

在celery_tasks目录下创建sms目录,用于放置发送短信的异步任务相关代码。

将提供的发送短信的云通讯SDK放到celery_tasks/sms/目录下。

在celery_tasks/sms/目录下创建tasks.py文件,用于保存发送短信的异步任务

# -*-coding:utf-8-*-
from celery_tasks.main import app
from meiduo_mall.libs.yuntongxun.sms import CCP

# 发送短信的方法
from meiduo_mall.utils.exceptions import logger


@ app.task(name="send_sms_code")
def send_sms_code(mobile, sms_code):
    """
    发送短信验证码的任务
    :param mobile1:
    :param sms_code:
    :return:
    """
    try:
        ccp = CCP()
        result = ccp.send_template_sms(mobile, [sms_code, 5], 1)
    except Exception as e:
        logger.error("发送验证码短信[异常][ mobile: %s, message: %s ]" % (mobile, e))
    else:
        if result == 0:
            logger.info("发送验证码短信[正常][ mobile: %s ]" % mobile)
        else:
            logger.warning("发送验证码短信[失败][ mobile: %s ]" % mobile)

在verifications/views.py中改写SMSCodeView视图,使用celery异步任务发送短信

from celery_tasks.sms.tasks import send_sms_code

class SMSCodeView(APIView):
    """发送短信验证码"""
    def get(self, request, mobile):
        """
        发送短信验证码
        url(r"^sms_codes/(?P<mobile>1[3-9]\d{9})/$", views.SMSCodeView.as_view()),
        :param request:
        :param mobile: 路径传参的手机号
        :return:
        """
        ...
        
		 # 使用selery发送短信
        send_sms_code.delay(mobile, sms_code,300//60)
        print("短信验证码:%s" % sms_code)
               
		...

启动celery异步任务:

celery -A celery_tasks.main worker -l info

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_35709559/article/details/84887789