一、编写利用腾讯云文件
在项目—>utils下创建一个文件tencentsms.py:
class TengXun(object):
def send_sms(self, code, mobile):
# 短信应用SDK AppID
appid = APP_ID # SDK AppID是1400开头,你们申请的appid
# 短信应用SDK AppKey 也是你们自己的
appkey = APP_KEY
# 需要发送短信的手机号码
phone_numbers = "{mobile}".format(mobile=mobile)
# 短信模板ID,需要在短信应用中申请
template_id = TEMPLATE_ID
# 签名
sms_sign = "你们自己签名的内容" # NOTE: 这里的签名"腾讯云"只是一个示例,真实的签名需要在短信控制台中申请,另外签名参数使用的是`签名内容`,而不是`签名ID`
ssender = SmsSingleSender(appid, appkey)
params = ["{code}".format(code=code), "3"] # 当模板没有参数时,`params = []`
try:
result = ssender.send_with_param(86, phone_numbers, template_id, params, sign=sms_sign, extend="",ext="") # 签名参数未提供或者为空时,会使用默认签名发送短信
except HTTPError as e:
print(e)
except Exception as e:
print(e)
print(result)
return result
二、DRF实现用户注册
1.在settings中设置手机号的正则:
# 手机号码正则表达式
REGEX_MOBILE = r"^1[3-9]\d{9}$"
当然可能你也可以把腾讯云的那些内容放在自己的本地设置里面安全一点。
2.接下来写我们的数据库表,
from datetime import datetime
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
"""用户"""
name = models.CharField(max_length=30, null=True, blank=True, verbose_name="姓名")
mobile = models.CharField(max_length=11, verbose_name="电话")
class Meta:
verbose_name_plural = verbose_name = "用户(CustomUser)"
ordering = ('id',)
def __str__(self):
return self.username
class VerifyCode(models.Model):
"""
短信验证
"""
code = models.CharField(max_length=10, verbose_name="验证码")
mobile = models.CharField(max_length=11, verbose_name="电话")
add_time = models.DateTimeField(default=datetime.now, verbose_name="添加时间")
class Meta:
verbose_name = "短信验证码"
verbose_name_plural = verbose_name
def __str__(self):
return self.code
接着在serserializer.py中设置序列化格式,并进行检验:
import re
from rest_framework import serializers
from django.contrib.auth import authenticate
from django.contrib.auth import get_user_model
from datetime import datetime
from datetime import timedelta
from django.utils.timezone import now
from rest_framework.validators import UniqueValidator
from .models import *
from mysite.settings import REGEX_MOBILE
class CustomUserSerializer(serializers.ModelSerializer):
class Meta:
model = CustomUser
fields = (
'url',
'id',
'username',
)
User = get_user_model()
class SmsSerializer(serializers.Serializer):
mobile = serializers.CharField(max_length=11)
def validate_mobile(self, mobile):
"""
验证手机号码
:param data:
:return:
"""
# 手机是否注册
# if User.objects.filter(mobile=mobile).count() != 0:
# raise serializers.ValidationError("用户已经存在")
# 验证手机号码是否合法
if not re.match(REGEX_MOBILE, mobile):
raise serializers.ValidationError("手机号码非法")
# 验证发送频率
one_min_ago = datetime.now() - timedelta(hours=0, minutes=1, seconds=0)
if VerifyCode.objects.filter(add_time__gt=one_min_ago, mobile=mobile).count():
raise serializers.ValidationError("距离上一次发送未超过60s")
return mobile
3.接下来写的view函数
# from rest_framework_jwt.serializers import jwt_payload_handler
# from rest_framework_jwt.utils import jwt_encode_handler
from .models import *
from .serializers import *
from common.views import CommonViewSet
from common.permissions import IsYourself
# from utils.tencentsms import send_sms_single
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import get_user_model
from random import choice
from rest_framework.mixins import CreateModelMixin
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework import status
from utils.tencentsms import TengXun
class CustomUserViewSet(
CommonViewSet,
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
viewsets.GenericViewSet
):
"""
list:
返回所有用户
retrieve:
返回一个用户
update:
更新用户信息
partial_update:
部分更新用户信息
"""
queryset = User.objects.all()
serializer_class = CustomUserSerializer
filter_backends = (filters.SearchFilter,)
search_fields = ['nickname', 'intro']
permission_classes_by_action = {
'list': [IsAuthenticated, IsYourself],
'retrieve': [IsAuthenticated, IsYourself],
'update': [IsAuthenticated, IsYourself],
'partial_update': [IsAuthenticated, IsYourself],
}
#这是我的权限设置你们可以删除或者写上自己的
class SmsCodeViewset(CreateModelMixin, viewsets.GenericViewSet):
"""
发送短信验证码
"""
serializer_class = SmsSerializer
def generate_code(self):
"""
生成四位数字的验证码
:return:
"""
seeds = "1234567890"
random_str = []
for i in range(4):
random_str.append(choice(seeds))
return "".join(random_str)
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
mobile = serializer.validated_data["mobile"]
teng_xun = TengXun()
code = self.generate_code()
sms_status = teng_xun.send_sms(code=code, mobile=mobile)
if sms_status["result"] != 0:
return Response({
"mobile": sms_status["errmsg"]
}, status=status.HTTP_400_BAD_REQUEST)
else:
code_record = VerifyCode(code=code, mobile=mobile)
code_record.save()
return Response({
"mobile": mobile
}, status=status.HTTP_201_CREATED)
class UserViewSet(CreateModelMixin, viewsets.GenericViewSet):
"""
用户
"""
serializer_class = UserRegSerializer
queryset = User.objects.all()
# 重新定义create函数 实现注册后自动登录
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = self.perform_create(serializer)
re_dict = serializer.data
# 移除 token
re_dict.pop('token', None)
# 移除 name
re_dict.pop('name', None)
headers = self.get_success_headers(serializer.data)
return Response(re_dict, status=status.HTTP_201_CREATED, headers=headers)
def perform_create(self, serializer):
return serializer.save()
这样子就可以完成短信注册的功能。当然还有写上路由,因为是我视图集的路由我就不具体展示的,怎么写路由网上的教程很多
标签:code,用户注册,mobile,self,验证码,import,class,serializer,drf From: https://www.cnblogs.com/shenhuang/p/18222670