前台
功能的开发
前台最基本的功能:
登录 注册
用户模型创建
models.py
# @ Time : 2020/5/21 15:30
# @ Author : Ellen
from exts import db
import shortuuid
from werkzeug.security import generate_password_hash, check_password_hash
import enum
from datetime import datetime
class GenderEnum(enum.Enum):
MALE = 1
FEMALE = 2
SECRET = 3
UNKNOW = 4
class FrontUser(db.Model):
# 有驼峰FrontUser front_user 无驼峰 Frontuser 则是frontuser
__tablename = 'front_user'
# 安全 用户id不用Integer,用String uuid shortuuid
id = db.Column(db.String(100), primary_key=True, default=shortuuid.uuid)
telephone = db.Column(db.String(11), nullable=False, unique=True)
username = db.Column(db.String(50), nullable=False)
_password = db.Column(db.String(100), nullable=False)
email = db.Column(db.String(100), unique=True)
realname = db.Column(db.String(50))
avatar = db.Column(db.String(100))
signature = db.Column(db.String(100))
gender = db.Column(db.Enum(GenderEnum), default=GenderEnum.UNKNOW)
join_time = db.Column(db.DateTime, default=datetime.now)
def __init__(self, *args, **kwargs):
if "password" in kwargs:
self.password = kwargs.get('password')
kwargs.pop('password')
# python 2
# super(FrontUser, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
@property
def password(self):
return self._password
@password.setter
def password(self, raw_password):
self._password = generate_password_hash(raw_password)
def check_password(self, raw_password):
result = check_password_hash(self.password, raw_password)
return result
views.py
from flask import Blueprint, views, render_template
front_bp = Blueprint("front", __name__)
@front_bp.route("/")
def index():
return "front index"
class SignupView(views.MethodView):
def get(self):
return render_template('front/front_signup.html')
front_bp.add_url_rule("/signup/", view_func=SignupView.as_view('signup'))
manage.py
添加用户
@manager.option('-t', '--telephone', dest='telephone')
@manager.option('-u', '--username', dest='username')
@manager.option('-p', '--password', dest='password')
def create_front_user(telephone, username, password):
user = FrontUser(telephone=telephone, username=username, password=password)
db.session.add(user)
db.session.commit()
print("Front用户添加成功")
front_signup.html
添加front/css/ front_signbase.css 及图片
<link href="{{ url_for('static', filename='front/css/front_signbase.css') }}" rel="stylesheet">
<img src="{{ url_for('static',filename='common/images/logo.png') }}"/>
前端界面
手机发送验证码功能
图形验证码功能
utils/send_msg.py
# @ Time : 2020/5/22 0:26
# @ Author : Ellen
from yunpian_python_sdk.model import constant as YC
from yunpian_python_sdk.ypclient import YunpianClient
def send_mobile_msg(mobile, code):
# 初始化client,apikey作为所有请求的默认值
clnt = YunpianClient('e8abe129a4e9f9a7c8c9adcxxxxxxx')
param = {YC.MOBILE: '186xxxxxxx', YC.TEXT: '【xxx】您的验证码是{}'.format(code)}
r = clnt.sms().single_send(param)
return r.code()
# 0 发送成功
# print(r.code())
# 发送成功的消息
# print(r.msg())
# print(r.data())
# 获取返回结果, 返回码:r.code(),返回码描述:r.msg(),API结果:r.data(),其他说明:r.detail(),调用异常:r.exception()
# 短信:clnt.sms() 账户:clnt.user() 签名:clnt.sign() 模版:clnt.tpl() 语音:clnt.voice() 流量:clnt.flow()
apps/common/forms.py
验证
# @ Time : 2020/5/22
# @ Author : Ellen
from wtforms import Form
from wtforms import StringField
from wtforms.validators import InputRequired, regexp
import hashlib
class SMSCaptchaForm(Form):
telephone = StringField(validators=[regexp(r'1[3456789]\d{9}')])
timestamp = StringField(validators=[regexp(r'\d{13}')])
sign = StringField(validators=[InputRequired()])
# 验证前端发送过来的sign和后端加密之后的sign 是否一致
def validate_sign(self, field):
telephone = self.telephone.data
timestamp = self.timestamp.data
sign = self.sign.data
# 服务端加密之后生成的
sign2 = hashlib.md5((timestamp + telephone + 'q3423805gdflvbdfvhsdoa`#$%').encode('utf-8')).hexdigest()
print("客户端sign %s" % sign)
print("服务端sign %s" % sign2)
if sign == sign2:
return True
else:
return False
加密
apps/common/views.py
Form表单验证后重写
# @ Time : 2020/5/22
# @ Author : Ellen
from utils import send_msg, restful
from flask import Blueprint, request
from utils.captcha import Captcha
from.forms import SMSCaptchaForm
common_bp = Blueprint("common", __name__, url_prefix='/c')
# # 只要收到当前的请求 就会发生短信
# @common_bp.route("/sms_captcha/", methods=['POST'])
# def sms_captcha():
# telephone = request.form.get('telephone')
#
# if not telephone:
# return restful.params_errors(message='请填写手机号码')
#
# captcha = Captcha.gene_text(number=4)
#
# if send_msg.send_mobile_msg(telephone, captcha) == 0:
# return restful.success()
# else:
# return restful.params_errors(message='发送失败')
@common_bp.route("/sms_captcha/", methods=['POST'])
def sms_captcha():
form = SMSCaptchaForm(request.form)
if form.validate():
return restful.success()
else:
return restful.params_errors(message='参数错误')