Flask(八)

一、钩子函数与上下文处理器

from flask import Flask,Response,request,session,render_template,g
import config
from exts import db,mail
from blueprints import qa_bp
from blueprints import user_bp
from flask_migrate import Migrate
from models import UserModel

app = Flask(__name__)
app.config.from_object(config)
db.init_app(app)
mail.init_app(app)

migrate=Migrate(app,db)

app.register_blueprint(qa_bp)
app.register_blueprint(user_bp)

#钩子函数
@app.before_request
def before_request():
    user_id=session.get("user_id")
    if user_id:
        try:
            user = UserModel.query.get(user_id)
            #给g绑定一个叫做user的变量,它的值是user这个变量
            #setattr(g,"user",user)
            g.user=user
        except:
            g.user=None

#请求来了-> before_request->视图函数->视图函数中返回的模板->context_processor

#上下文处理器
@app.context_processor
def context_processor():
    if hasattr(g,"user"):
        return {"user":g.user}
    else:
        return {}


if __name__ =='__main__':
    app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}{% endblock %}</title>
    <link rel="stylesheet" href="{{url_for('static',filename='bootstrap/bootstrap@4.6.min.css')}}">
    <link rel="stylesheet" href="{{url_for('static',filename='css/init.css')}}">
  {% block head %} {% endblock %}
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <div class="container">
  <a class="navbar-brand" href="#">问答</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="navbarSupportedContent">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item active">
        <a class="nav-link" href="#">首页 <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">发布问答</a>
      </li>
         <li class="nav-item ml-2">
          <form class="form-inline my-2 my-lg-0">
            <input class="form-control mr-sm-2" type="search" placeholder="关键字" aria-label="Search">
            <button class="btn btn-outline-success my-2 my-sm-0" type="submit">搜索</button>
         </form>
    </li>
    </ul>
     <ul class="navbar-nav">
      {% if user %}
       <li class="nav-item">
       <spam class="nav-link">{{user.username}}</spam>
       </li>
       <li class="nav-item">
        <a class="nav-link" href="{{url_for('user.register')}}">退出登录</a>
      </li>
       {% else %}
       <li class="nav-item">
        <a class="nav-link" href="{{url_for('user.login')}}">登录 </a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="{{url_for('user.register')}}">注册</a>
      </li>
       {% endif %}
    </ul>
    </div>
  </nav>
</div>
<div class="container">{% block body %}{% endblock %}</div>
</nav>
</body>
</html>

登录后会是这样的页面:

而没登陆是这样的:

 

二、退出登录功能

import random
import string

from flask import Blueprint,render_template,request,redirect,url_for,jsonify,session,flash
from exts import mail,db
from flask_mail import Message
from models import EmailCaptchaModel,UserModel
from datetime import datetime
from .forms import  RegisterForm
from werkzeug.security import generate_password_hash,check_password_hash

bp=Blueprint("user",__name__,url_prefix="/user")

#实现登录功能
@bp.route("/login",method=['GET','POST'])
def login():
    if request.method=='GET':
        return render_template("login.html")
    else:
        form = LoginForm(request.form)
        if form.validate():
            email=form.email.data
            password=form.password.data
            user=UserModel.query.filter_by(email=email).first()
            if user and check_password_hash(user.password,password):
                session['user_id']=user.id
                return redirect("/")
            else:
                flash("邮箱和密码不匹配!")
                return redirect(url_for("user.login"))
        else:
            flash("邮箱或密码格式错误!")
            return redirect(url_for("user.login"))


@bp.route("/register",methods=['GET','POST'])
def register():
    if request.method =='GET':
        return render_template("register.html")
    else:
        form = RegisterForm(request.form)
        if form.validate():
            email = form.email.data
            username = form.username.data
            password = form.password.data

            hash_password=generate_password_hash(password)   #密码加密
            user = UserModel(email=email, username=username, password=password)
            db.session.add(user)
            db.session.commit()
            return redirect(url_for("user.login"))
        else:
            return redirect(url_for("user.register"))

#退出登录
@bp.route("/logout")
def logout():
    #清除session中所有的数据
    session.clear()
    return redirect(url_for('user.login'))

@bp.route("/captcha",methods=['POST'])
def get_captcha():
    email=request.form.get("email")
    letter=string.ascii_letters+string.digits
    captcha="".join(random.sample(letter,4))
    if email:
        message = Message(
            subject='邮箱测试',
            recipients=['2780038443@qq.com'],
            body=f"您的注册验证码是:{captcha},请不要告诉任何人哦!"
        )
        mail.send(message)
        captcha_model=EmailCaptchaModel.query.filter_by(email=email).first()
        if captcha_model:
            captcha_model.captcha=captcha
            captcha_model.create_time=datetime.now()
            db.session.commit()
        else:
            captcha_model=EmailCaptchaModel(email=email,captcha=captcha)
            db.session.add(captcha_model)
            db.session.commit()
            #code:200。成功的,正常的请求
        return jsonify({"code":200})
    else:
        #code:400  客户端错误
        return jsonify({"code":400,"message":"请先传递邮箱!"})


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}{% endblock %}</title>
    <link rel="stylesheet" href="{{url_for('static',filename='bootstrap/bootstrap@4.6.min.css')}}">
    <link rel="stylesheet" href="{{url_for('static',filename='css/init.css')}}">
  {% block head %} {% endblock %}
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <div class="container">
  <a class="navbar-brand" href="#">问答</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="navbarSupportedContent">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item active">
        <a class="nav-link" href="#">首页 <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">发布问答</a>
      </li>
         <li class="nav-item ml-2">
          <form class="form-inline my-2 my-lg-0">
            <input class="form-control mr-sm-2" type="search" placeholder="关键字" aria-label="Search">
            <button class="btn btn-outline-success my-2 my-sm-0" type="submit">搜索</button>
         </form>
    </li>
    </ul>
     <ul class="navbar-nav">
      {% if user %}
       <li class="nav-item">
       <spam class="nav-link">{{user.username}}</spam>
       </li>
       <li class="nav-item">
        <a class="nav-link" href="{{url_for('user.logout')}}">退出登录</a>
      </li>
       {% else %}
       <li class="nav-item">
        <a class="nav-link" href="{{url_for('user.login')}}">登录 </a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="{{url_for('user.register')}}">注册</a>
      </li>
       {% endif %}
    </ul>
    </div>
  </nav>
</div>
<div class="container">{% block body %}{% endblock %}</div>
</nav>
</body>
</html>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值