萬商超信
django框架主要用來做什么(阿里云短信服務(wù)怎么弄)
2021-11-20 12:04
新建項目
新建名為users的app,將users加入到INSTALLED_APPS中:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'users',
]
為了不使用django自增長的主鍵id,現(xiàn)在我們使用uuid來作為自增長的主鍵
pip install django-shortuuidfield
項目中使用到了redis 請先確保你的本機或者服務(wù)器安裝了redis
在項目中安裝redis
Pip install django-redis==4.10.0
配置settings.py文件
# redis配置
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100}
# "PASSWORD": "密碼",
}
}
}
REDIS_TIMEOUT=7*24*60*60
CUBES_REDIS_TIMEOUT=60*60
NEVER_REDIS_TIMEOUT=365*24*60*60
也可以使用memcached,關(guān)于memcached配置如下
# 緩存配置
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211'
}
}
創(chuàng)建用戶表
現(xiàn)在開始創(chuàng)建用戶表
# users/models.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
from shortuuidfield import ShortUUIDField
# Create your models here.
class UserManager(BaseUserManager):
'''
_create_user:私有方法,用來創(chuàng)建用戶
create_user:創(chuàng)建普通用戶
create_superuser:創(chuàng)建超級管理員
'''
def _create_user(self, telephone, username, password, **kwargs):
if not telephone:
raise ValueError('請輸入手機號碼')
if not username:
raise ValueError('請輸入用戶名')
if not password:
raise ValueError('請輸入密碼')
user = self.model(telephone=telephone, username=username, password=password, **kwargs)
user.set_password(password)
user.save()
return user
def create_user(self, telephone, username, password, **kwargs):
kwargs['is_superuser'] = False
return self._create_user(telephone=telephone, username=username, password=password, **kwargs)
def create_superuser(self, telephone, username, password, **kwargs):
kwargs['is_superuser'] = True
kwargs['is_staff'] = True
return self._create_user(telephone, username, password, **kwargs)
class User(AbstractBaseUser, PermissionsMixin):
# 不使用默認(rèn)自增長的主鍵
uid = ShortUUIDField(primary_key=True)
telephone = models.CharField(max_length=11, unique=True)
email = models.EmailField(unique=True, null=True)
username = models.CharField(max_length=100)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
data_joined = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'telephone' # 使用手機號碼登錄
REQUIRED_FIELDS = ['username']
EMAIL_FIELD = 'email'
objects = UserManager()
def get_full_name(self):
return self.username
def get_short_name(self):
return self.username
遷移數(shù)據(jù)表
python manage.py makemigrations
python manage.py migrate
在settings.py中配置AUTH_USER_MODEL='appname.User'
python AUTH_USER_MODEL = 'users.User'
編寫表單規(guī)則
在app中新建forms表單
# users/forms.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@author: 小羊駝
@contact: wouldmissyou@163.com
@time: 2020/6/11 上午9:13
@file: forms.py
@desc:
"""
from django import forms
from django.core.cache import cache
from .models import User
class FormMixin(object):
'''
get_errors: 獲取錯誤信息并返回成json
'''
def get_errors(self):
if hasattr(self,'errors'):
errors = self.errors.get_json_data()
new_errors = {}
for key, message_dicts in errors.items():
messages = []
for message in message_dicts:
messages.append(message['message'])
new_errors[key] = messages
return new_errors
else:
return {}
class RegisterForm(forms.Form, FormMixin):
# 注冊表單
telephone = forms.CharField(max_length=11)
username = forms.CharField(max_length=20)
password1 = forms.CharField(max_length=20, min_length=6,
error_messages={"max_length": "密碼最多不能超過20個字符!", "min_length": "密碼最少不能少于6個字符!"})
password2 = forms.CharField(max_length=20, min_length=6,
error_messages={"max_length": "密碼最多不能超過20個字符!", "min_length": "密碼最少不能少于6個字符!"})
sms_captcha = forms.CharField(min_length=4, max_length=4)
def clean(self):
cleaned_data = super(RegisterForm, self).clean()
# 驗證密碼
password1 = cleaned_data.get('password1')
password2 = cleaned_data.get('password2')
if password1 != password2:
raise forms.ValidationError('兩次密碼輸入不一致!')
# 驗證手機號和驗證碼
telephone = cleaned_data.get('telephone')
sms_captcha = cleaned_data.get('sms_captcha')
cached_sms_captcha = cache.get(telephone)
# if not cached_sms_captcha or cached_sms_captcha.lower() != sms_captcha.lower(): # 如果驗證碼中有字母 則使用這個,驗證字母小寫是否一致
if cached_sms_captcha != sms_captcha:
raise forms.ValidationError('短信驗證碼錯誤!')
# 驗證是否已注冊
exists = User.objects.filter(telephone=telephone).exists()
if exists:
raise forms.ValidationError('該手機號碼已經(jīng)被注冊!')
return cleaned_data
編寫視圖
安裝阿里云短信sdk
pip install aliyun-python-sdk-dysmsapi
安裝完成后根目錄新建utils包將aliyunsdk放在utils包里,修改aliyunsms.py
# -*- coding: utf-8 -*-
import sys
from aliyunsdkdysmsapi.request.v20170525 import SendSmsRequest
from aliyunsdkdysmsapi.request.v20170525 import QuerySendDetailsRequest
from aliyunsdkcore.client import AcsClient
import uuid
from aliyunsdkcore.profile import region_provider
from aliyunsdkcore.http import method_type as MT
from aliyunsdkcore.http import format_type as FT
import json
"""
短信業(yè)務(wù)調(diào)用接口示例,版本號:v20170525
Created on 2017-06-12
"""
ACCESS_KEY_ID = "XXXX" # 填寫你自己的ACCESS_KEY
ACCESS_KEY_SECRET = "XXXXX" # 填寫你自己的ACCESS_KEY_SECRET
# 注意:不要更改
REGION = "cn-hangzhou"
PRODUCT_NAME = "Dysmsapi"
DOMAIN = "dysmsapi.aliyuncs.com"
acs_client = AcsClient(ACCESS_KEY_ID, ACCESS_KEY_SECRET, REGION)
region_provider.add_endpoint(PRODUCT_NAME, REGION, DOMAIN)
def send_sms(phone_numbers,code):
business_id = uuid.uuid1()
sign_name = 'XXXXX' # 模板名稱
template_code = 'XXXXX' # 模板code
template_param = json.dumps({"code":code})
smsRequest = SendSmsRequest.SendSmsRequest()
# 申請的短信模板編碼,必填
smsRequest.set_TemplateCode(template_code)
# 短信模板變量參數(shù)
if template_param is not None:
smsRequest.set_TemplateParam(template_param)
# 設(shè)置業(yè)務(wù)請求流水號,必填。[django框架主要用來做什么(阿里云短信服務(wù)怎么弄)]。
smsRequest.set_OutId(business_id)
# 短信簽名
smsRequest.set_SignName(sign_name)
# 短信發(fā)送的號碼列表,必填。
smsRequest.set_PhoneNumbers(phone_numbers)
# 調(diào)用短信發(fā)送接口,返回json
smsResponse = acs_client.do_action_with_exception(smsRequest)
return smsResponse
在utils中新建一個restful.py 此文件用來處理服務(wù)端返回的信息
# encoding: utf-8
from django.http import JsonResponse
class HttpCode(object):
ok = 200
paramserror = 400
unauth = 401
methoderror = 405
servererror = 500
# {"code":400,"message":"","data":{}}
def result(code=HttpCode.ok, message="", data=None, kwargs=None):
json_dict = {"code": code, "message": message, "data": data}
if kwargs and isinstance(kwargs, dict) and kwargs.keys():
json_dict.update(kwargs)
return JsonResponse(json_dict)
def ok():
return result()
def params_error(message="", data=None):
return result(code=HttpCode.paramserror, message=message, data=data)
def unauth(message="", data=None):
return result(code=HttpCode.unauth, message=message, data=data)
def method_error(message='', data=None):
return result(code=HttpCode.methoderror, message=message, data=data)
def server_error(message='', data=None):
return result(code=HttpCode.servererror, message=message, data=data)
編寫view.py
from django.shortcuts import render
import random
from django.views import View
from django.contrib.auth import login
from .forms import RegisterForm
from utils import restful
from utils.aliyunsdk import aliyunsms
from django.core.cache import cache
from django.contrib.auth import get_user_model
User = get_user_model()
class IndexView(View):
def get(self, request):
return render(request,'index.html')
def post(self, request):
form = RegisterForm(request.POST)
if form.is_valid():
telephone = form.cleaned_data.get('telephone')
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password1')
user = User.objects.create_user(telephone=telephone, username=username, password=password)
login(request, user) # 注冊完之后直接登錄
return restful.ok()
else:
errors = form.get_errors()
# {"password":['密碼最大長度不能超過20為!','xxx'],"telephone":['xx','x']}
print(errors)
return restful.params_error(message=errors)
# 數(shù)字表示生成幾位, True表示生成帶有字母的 False不帶字母的
def get_code(n=4, alpha=True):
s = '' # 創(chuàng)建字符串變量,存儲生成的驗證碼
for i in range(n): # 通過for循環(huán)控制驗證碼位數(shù)
num = random.randint(1, 9) # 生成隨機數(shù)字0-9
if alpha: # 需要字母驗證碼,不用傳參,如果不需要字母的,關(guān)鍵字alpha=False
upper_alpha = chr(random.randint(65, 90))
lower_alpha = chr(random.randint(97, 122))
num = random.choice([num, upper_alpha, lower_alpha])
s = s + str(num)
return s
def sms_captcha(request):
# /sms_captcha/?telephone=xxx
telephone = request.GET.get('telephone')
code = get_code(4, False) # 生成4為不帶字母的數(shù)字
# code = '1111' # 生成4為不帶字母的數(shù)字
cache.set(telephone, code)
result = aliyunsms.send_sms(telephone, code)
print(result)
print('發(fā)送的驗證碼:',code)
print('判斷緩存中是否有:', cache.has_key(telephone))
print('獲取Redis驗證碼:', cache.get(telephone))
return restful.ok()
最后別忘了配置路由
path('', IndexView.as_view(), name='register'),
path('sms_captcha', views.sms_captcha),
最后在前端頁面使用ajax方式提交就行了