学城项目判断手机号是否存在接口,多方式登录接口,短信发送接口和短信发送模块封装搭建

1.前后端项目上传远程git仓库

2.判断手机号是否存在的接口 (6.21)

/1  在apps/user 文件夹下添加路由

from rest_framework.routers import SimpleRouter
from .views import UserView
router = SimpleRouter()
router.register('userinfo', UserView, 'userinfo')
urlpatterns = [
]
urlpatterns += router.urls

/2  在apps/user 文件夹下的views文件夹中写入判断手机号是否存在的逻辑

class UserView(ViewSet):
    # 验证手机号是否存在接口--->get请求--->和数据库有关,但是不需要序列化--->自动生成路由
    @action(methods=['GET'],detail=False)
    def check_mobile(self,request,*args,**kwargs):  # 虽然没有,写上为之后有了做准备
        try:
            # 从前端取传入的手机号
            mobile = request.query_params.get('mobile',None)
            user = User.objects.filter(mobile=mobile)
            return APIResponse(msg='手机号已存在')
        except Exception as e:
            raise APIException('手机号不存在')
            # return APIResponse('手机号不存在')

/3  在外部的urls中进行路由分发

from django.views.static import serve
from django.conf import settings
urlpatterns = [
    path('admin/', admin.site.urls),
    # path('index/', views.index),
    # path('exception/', views.ExceptionTestView.as_view()),
    # path('response/', views.ResponseView.as_view()),
    # 路由分发
    path('api/v1/home/', include('home.urls')),
    path('api/v1/user/', include('user.urls')), # http://127.0.0.1:8000/api/v1/user/user/check_mobile
    path('media/<path:path>',serve,{'document_root':settings.MEDIA_ROOT})
]

/4  在postman中进行测试

输入http://127.0.0.1:8000/api/v1/user/user/check_mobile?mobile=xxxx进行测试

3.多方式登录接口 

/1 整体逻辑(需要哪些接口):

  校验手机号是否存在的接口

  多方式登录接口

  发送短信接口

  短信登录接口

  短信注册接口

4.多方式登录接口 

/1 将多方式登录的接口和检测手机号是否存在的接口写在一起

# 多方式登录--->需要用到序列化类--->继承视图类基类
# post请求--->前端携带数据 {username:xxx,password:123}--->post请求
@action(methods=['post'],detail=False)
def mul_login(self,request,*args,**kwargs):
    # 校验的过程写到序列化类中
    ser = self.get_serializer(data=request.data) # 进行序列化
    # 只要执行 is_valid 就会执行字段自己的校验,例如全局和局部钩子
    # 在这段程序中我们需要在序列化类中写自己的校验规则,生成token串
    ser.is_valid(raise_exception=True) # 进行校验,如果失败,则抛出异常
    username = ser.context.get('username')
    token = ser.context.get('token')
    icon = ser.context.get('icon')
    # 登录成功会显示出token和用户名
    return APIResponse(username=username,token=token,icon=icon)

/2 校验的过程和全局钩子

  1 序列化类:

class LoginUserSerializer(serializers.ModelSerializer):
    # 序列化类自身的限制
    # 需要对字段进行校验,例如唯一性的校验,所以重写该字段
    username = serializers.CharField(max_length=9,required=True)
    class Meta:
        model = User
        fields = ['username','password']  # 只做数据校验,括号里边写需要校验的字段

  2 反序列化校验的方法:

# 对于用户名和密码的校验
def _get_user(self, attrs):
    username = attrs.get('username')
    password = attrs.get('password')
    user = User.objects.filter(Q(username=username) | Q(mobile=username) | Q(email=username)).first()
    if user and user.check_password(password):
        # 用户名存在,返回出用户信息
        return user
    else:
        # 否则就抛出异常
        raise APIException('用户名和密码错误')
#  获取jwt_token
def _get_token(self,user):
    payload = jwt_payload_handler(user)
    token = jwt_encode_handler(payload)
    return token

  3 全局钩子

# 全局钩子
# 写上 1.验证用户名密码的的逻辑 2.以及签发token的逻辑
# 多方式登录,username可以是用户名,邮箱,电话
# 之前用的是正则匹配 今天使用Q查询
def validate(self,attrs):
    user = self._get_user(attrs)
    token = self._get_token(user) # 传入用户,根据用户来签发token
    # 把user和token放在序列化类的context
    # context是上下文
    self.context['username'] = user.username
    self.context['icon'] = str(user.icon)
    self.context['token'] = token
    return attrs

/3  无需配置路由 

/4  在postman中进行测试

  选择post方式,输入http://127.0.0.1:8000/api/v1/user/userinfo/mul_login/

  在body中携带用户名和密码

 补充:context上下文
context是一个字典对象
 

5. 短信发送模块 

/1  在pycharm中安装短信发送的模块

  打开腾讯云短信的网址。通过连接:https://cloud.tencent.com/document/product/382/43196 跳转到gitee

  获取到安装命令:pip install --upgrade tencentcloud-sdk-python

  打开Terminal输入,安装成功

/2   在腾讯云平台中获取签名和模版名

  在scripts文件夹下建立发送短信的模块文件sms_send_demo

  将签名和模版名替换到其中

6. 短信发送模块的封装 和 接口的创建

/1   建立封装所在的文件夹

  在luffy下的libs文件夹中建立包send_text_sms,并新建settings.py和sms.py文件

/2  写入需要封装的代码以及它的配置文件

   在sms.py中写入sms_send_demo中的代码

   并在settings.py中配置好sms代码中需要用到的变量,将他们写活

/3  在视图类中写发送短信的接口

# 发送短信验证码的接口
@action(methods=['GET'],detail=False)
def send_sms(self,request,*args,**kwargs):
    # 前端需要把发送的手机号穿传入到后端 (因为是get方法,所以手机号存在地址栏中)
    mobile = request.query_params.get('mobile',None) # 如果拿不到手机号就输出none,在下面抛出异常
    code = get_code() # 在后面需要用到code,所以要存起来
    # 把code存到缓存中
    cache.set('send_sms_code_%s'% mobile , code)
    # 把code从缓存中取出来
    # cache.get('send_sms_code_%s'%mobile)
    if mobile and send_sms_by_mobile(mobile,code):
        return APIResponse(msg='发送成功')
    raise APIException('发送信息失败')

 

  
posted @ 2023-06-26 22:51  ranbo145  阅读(60)  评论(0)    收藏  举报