Flask基础学习3

参考视频:41-【实战】答案列表的渲染_哔哩哔哩_bilibili


flask 实现发送短信功能

pip install flask-mail # 安装依赖

我这里用登录的网易邮箱获取的授权码(登录QQ邮箱的授权码总是断开收不到邮件),

# config
# config mail
MAIL_SERVER = 'smtp.163.com'
MAIL_USE_SSL = True
MAIL_PORT = 465
MAIL_USERNAME = 'xxx@163.com'
MAIL_PASSWORD='xxx'
MAIL_DEFAULT_SENDER  = 'xxx@163.com'

@bp.route('/mail/test')
def mail_test():
    message = Message(subject='mail test',recipients=['xxx@qq.com'],body='xxx')
    mail.send(message)

运行结果:

邮箱发送验证功能实现

@bp.route('/captcha/email')
def get_mail_cptcha():
    email = request.args.get('email')
    source= string.digits*4
    cap = random.sample(source,4)
    cap  = ''.join(cap)
    message = Message(subject='菜鸟学习测试', recipients=[email], body='你的验证码是:{}'.format(cap))
    mail.send(message)

    email_capt = EmailCaptchModel(email=email,captcha=cap)
    db.session.add(email_capt)
    db.session.commit()

    return jsonify({'code':200,'message':'','data':None})

查看DB数据

注册表单验证实现:

# blueprints/forms.py
import wtforms
from wtforms.validators import Email,Length,EqualTo
from models import UserModel,EmailCaptchModel

class RegisterForm(wtforms.Form):
    email = wtforms.StringField(validators=[Email(message="邮箱格式错误!")])
    captcha = wtforms.StringField(validators=[Length(min=4,max=4,message="验证码格式错误!")])
    username = wtforms.StringField(validators=[Length(min=3,max=20,message="用户名格式错误!")])
    password = wtforms.StringField(validators=[Length(min=3,max=20,message="密码长度为4-20位!")])
    password_confirm = wtforms.StringField(validators=[EqualTo('password',message="两次输入的错误不一致!")])

    def validate_email(self, field):
        email = field.data
        user = UserModel.query.filter_by(email=email).first()
        if user:
            raise wtforms.ValidationError(message='该邮箱已经被注册!')

    def validate_captcha(self,field):
        captcha = field.data
        email = self.email.data
        captcha_model = EmailCaptchModel.query.filter_by(email=email,captcha=captcha).first()
        if not captcha_model:
            print('邮箱或验证码格式错误!')
            # raise wtforms.ValidationError(message='邮箱或验证码格式错误!')
        # else:
        #     db.session.delete(captcha_model)
        #     db.session.commit()

注册功能后端的实现

# blueprints/auth.py
@bp.route('/register',methods = ['POST','GET'])
def register():
    if request.method == 'GET':
        return render_template('regist.html')
    form  = RegisterForm(request.form)
    if form.validate():
        email = form.email.data
        username= form.username.data
        password = form.password.data
        user= UserModel(email=email,username=username,password=generate_password_hash(password))
        db.session.add(user)
        db.session.commit()
        return redirect(url_for('auth.login'))
    else:
        print(form.data)
        print(form.errors)
        return redirect(url_for('auth.register'))

运行结果:

登录功能后端的实现,并将session信息加密保存到cookie中

# forms.py
class LoginForm(wtforms.Form):
    email = wtforms.StringField(validators=[Email(message="邮箱格式错误!")])
    print(wtforms.validators.Email)
    password = wtforms.StringField(validators=[Length(min=4, max=20, message="密码长度为4-20位!")])

# auth.py
@bp.route('/login',methods = ['POST','GET'])
def login():
    if request.method == 'GET':
        return render_template('login.html')
    form = LoginForm(request.form)
    print(form.data)
    if form.validate():
        email = form.email.data
        password = form.password.data
        user = UserModel.query.filter_by(email=email).first()
        if not user:
            print('邮箱在数据库中不存在')
            return redirect(url_for('auth.login'))
        if check_password_hash(user.password,password):
            # cookie 存在浏览器上
            # flsk的session 是加密存在在cookie
            session['user.id'] = user.id
            return redirect(url_for('auth.index'))
        else:
            print('密码错误')
            return redirect(url_for('auth.login'))
    else:
        print(form.errors)
        return redirect(url_for('auth.login'))

注意: 配置session信息时要配置自定义密钥,否则会报错

# 配置session
SECRET_KEY = 'DSAFSDFASFASDFADFSDSASFD' # 无要求,自定义

两个钩子的运用及实现

python 复制代码
# from flask import g
# 全局变量g
@login_required
def my_before_request():
    user_id = session.get('user_id')
    if user_id:
        user = UserModel.query.get(user_id)
        setattr(g,'user',user)
    else:
        setattr(g,'user',None)

@app.context_processor
def my_context_processor():
    return {'user':g.user}

配置用户的登录名称显示及注销功能的实现

python 复制代码
{% if user %}
  <li><a href="#">{{ user.username }}</a></li>
  <li><a href="{{ url_for('auth.logout') }}">注销</a></li>
{% else %}
  <li><a href="{{url_for('auth.login')}}">登录</a></li>
  <li><a href="{{url_for('auth.register')}}">注册</a></li>
{% endif %}
python 复制代码
@bp.route('/logout')
def logout():
    session.clear()
    return render_template('index.html')

发布问答后端接口的实现

python 复制代码
# model.py
class QuestionModel(db.Model):
    __tablename__ = 'question'
    id = db.Column(db.Integer,primary_key=True,autoincrement=True)
    title = db.Column(db.String(1000),nullable=False)
    content = db.Column(db.Text,nullable=False)
    create_time = db.Column(db.DateTime,default=datetime.now())
    author_id = db.Column(db.Integer,db.ForeignKey('user.id'))
    author = db.relationship(UserModel,backref = 'questions')


# form 验证器
class QuestionForm(wtforms.Form):
    title = wtforms.StringField(validators=[Length(min=4, max=100, message="标题格式错误!")])
    context = wtforms.StringField(validators=[Length(min=3, max=200, message="内容格式错误")])
python 复制代码
from flask import Blueprint,request,render_template
from .forms import QuestionForm
from decorators import login_required
from models import QuestionModel
from exts import db
bp=Blueprint('qa',__name__,url_prefix='/qa')

@bp.route('/question',methods = ['POST','GET'])
def question():
    if request.method == 'GET':
        return render_template('question.html')
    else:
        form  =QuestionForm(request.form)
        print(form.data)
        if form.validate():
            title = form.title.data
            context = form.context.data
            question = QuestionModel(title=title,content=context,author=g.user)
            db.session.add(question)
            db.session.commit()
            return render_template('index.html')
        else:
            print(form.errors)
            return render_template('question.html')

登录装饰器的实现,只有在登录后才可进行发布问答

python 复制代码
# 自定义登录装饰器
from functools import wraps
from flask import g,redirect,url_for
def login_required(func):
    # 保留func的信息
    @wraps(func)
    def inner(*args,**kwargs):
        if g.user:
            return func(*args,**kwargs)
        else:
            return redirect(url_for('auth.login'))
    return inner


# 配置装饰器
@login_required
def question()

问答列表首页功能实现:

python 复制代码
@bp.route('/')
def index():
    # 根据创建时间倒序排列
    questions = QuestionModel.query.order_by(QuestionModel.create_time.desc()).all()
    return render_template('index.html',questions=questions)

发布问答详细的功能实现

python 复制代码
@bp.route('/qa/detail/<qa_id>')
def qa_detail(qa_id):
    question=QuestionModel.query.get(qa_id)
    return render_template('detail.html',question=question)


@bp.post('/answer/public')
@login_required
def public_answer():
    form = AnswerForm(request.form)
    if form.validate():
        content = form.context.data
        question_id = form.question_id.data
        answer = AnswerModel(content=content,question_id=question_id,author_id=g.user.id)
        db.session.add(answer)
        db.session.commit()
        return redirect(url_for('qa.qa_detail',qa_id=question_id))
    else:
        print(form.errors)
    return redirect(url_for('qa.qa_detail', qa_id=request.form.get('question_id')))

搜索功能的实现

python 复制代码
@bp.route('/search')
def search():
    q = request.args.get('q')
    # 搜索标题的关键字
    questions= QuestionModel.query.filter(QuestionModel.title.contains(q)).all()
    return render_template('index.html',questions=questions)

okok

相关推荐
-一杯为品-40 分钟前
【51单片机】程序实验5&6.独立按键-矩阵按键
c语言·笔记·学习·51单片机·硬件工程
傻啦嘿哟1 小时前
如何使用 Python 开发一个简单的文本数据转换为 Excel 工具
开发语言·python·excel
B站计算机毕业设计超人1 小时前
计算机毕业设计SparkStreaming+Kafka旅游推荐系统 旅游景点客流量预测 旅游可视化 旅游大数据 Hive数据仓库 机器学习 深度学习
大数据·数据仓库·hadoop·python·kafka·课程设计·数据可视化
风尚云网2 小时前
风尚云网前端学习:一个简易前端新手友好的HTML5页面布局与样式设计
前端·css·学习·html·html5·风尚云网
IT古董2 小时前
【人工智能】Python在机器学习与人工智能中的应用
开发语言·人工智能·python·机器学习
湫ccc2 小时前
《Python基础》之pip换国内镜像源
开发语言·python·pip
hakesashou2 小时前
Python中常用的函数介绍
java·网络·python
菜鸟的人工智能之路2 小时前
极坐标气泡图:医学数据分析的可视化新视角
python·数据分析·健康医疗
菜鸟学Python2 小时前
Python 数据分析核心库大全!
开发语言·python·数据挖掘·数据分析
小白不太白9502 小时前
设计模式之 责任链模式
python·设计模式·责任链模式