flask基础 制作博客注册登录系统(上)

#用户管理

用户注册激活

  1. 在基础模板base.html中,导航条上添加注册的点击链接,如下:

    <li><a href="{{ url_for('user.register') }}">注册</a></li>
    

    因为我们的视图函数是写在蓝本中的,因此反向构造路由时需要指定蓝本,

    若不指定蓝本(就是视图前面只有一个.),默认表示当前的蓝本。

  2. 添加用户注册的视图函数,如下:

    @user.route('/register/')
    def register():
        return render_template('user/register.html')
    
  3. 创建用户注册的模板文件,如下:

    {% extends 'common/base.html' %}
    
    {% block title %}用户注册{% endblock %}
    
    {% block page_content %}
        欢迎注册
    {% endblock %}
    
  4. 添加用户注册的表单,如下:

    from flask_wtf import FlaskForm
    from wtforms import StringField, PasswordField, SubmitField
    from wtforms.validators import DataRequired, Length, EqualTo, Email
    
    # 用户注册表单
    class RegisterForm(FlaskForm):
      	username = StringField('用户名', validators=[DataRequired(), Length(4, 20, message='用户名只能在4~20个字符之间')])
       	password = PasswordField('密码', validators=[DataRequired(), Length(6, 20, message='密码长度必须在6~20个字符之间')])
       	confirm = PasswordField('确认密码', validators=[EqualTo('password', message='两次密码不一致')])
       	email = StringField('邮箱', validators=[Email(message='邮箱格式不正确')])
       	submit = SubmitField('立即注册')
    

    在视图函数中创建表单对象,然后分配到模板文件中并完成渲染

  5. 添加表单的验证逻辑,如下:

    @user.route('/register/', methods=['GET', 'POST'])
       def register():
           form = RegisterForm()
           if form.validate_on_submit():
               # 根据表单数据,创建用户对象
               # 将用户对象保存到数据库
               # 发送用户账户的激活邮件
               # 弹出flash消息提示用户
               flash('用户已注册,请点击邮件中的链接以完成激活')
               # 跳转到首页/登录页面
               return redirect(url_for('main.index'))
           return render_template('user/register.html', form=form)   
    
  6. 添加用户模型,如下:

    from app.extensions import db
    from werkzeug.security import generate_password_hash, check_password_hash
    
    class User(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        username = db.Column(db.String(32), unique=True)
        password_hash = db.Column(db.String(128))
        email = db.Column(db.String(64), unique=True)
        confirmed = db.Column(db.Boolean, default=False)
    
        # 保护密码属性
        @property
        def password(self):
            raise AttributeError('密码是不可读属性')
    
        # 设置密码时,保存加密后的hash值
        @password.setter
        def wrqf(self, password):
            self.password_hash = generate_password_hash(password)
    
        # 密码校验,正确返回True,错误返回False
        def verify_password(self, password):
            return check_password_hash(self.password_hash, password)
    
    1. 新建的模型必须在外部包含一次,否则项目根本不知道有这个模型,迁移失败;
    2. 创建或修改模型后记得及时完成迁移操作,以防模型与数据表不对应。
  7. 添加账户激活时的token生成与检验

    from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
    
    class User(db.Model):
        ...
        # 生成账户激活的token
        def generate_activate_token(self, expires_in=3600):
            s = Serializer(current_app.config['SECRET_KEY'], 
            				expires_in=expires_in)
            return s.dumps({'id': self.id})
    
        # 校验账户激活的token
        @staticmethod
        def check_activate_token(token):
            s = Serializer(current_app.config['SECRET_KEY'])
            try:
                data = s.loads(token)
            except:
                return False
            u = User.query.get(data.get('id'))
            if not u:
                # flash('用户不存在')
                return False
            if not u.confirmed:     # 账户没有激活
                u.confirmed = True
                db.session.add(u)
            return True
    
  8. 完整注册实现,如下:

    @user.route('/register/', methods=['GET', 'POST'])
    def register():
        form = RegisterForm()
        if form.validate_on_submit():
            # 根据表单数据,创建用户对象
            u = User(username=form.username.data,
                     password=form.password.data,
                     email=form.email.data)
            # 将用户对象保存到数据库
            db.session.add(u)
            # 因为下面生成token需要使用id,此时还没有,因此需要手动提交
            db.session.commit()
            # 生成token
            token = u.generate_activate_token()
            # 发送用户账户的激活邮件
            send_mail(u.email, '账户激活', 'email/activate', 
            		username=u.username, token=token)
            # 弹出flash消息提示用户
            flash('用户已注册,请点击邮件中的链接以完成激活')
            # 跳转到首页/登录页面
            return redirect(url_for('main.index'))
        return render_template('user/register.html', form=form)
    
  9. 添加激活邮件的模板

    <h1>Hello {{ username }}</h1>
    <p>激活账户请点击右边链接<a href="{{ url_for('user.activate', token=token, _external=True) }}">激活</a></p>
    
  10. 添加邮件激活的路由

@user.route('/activate/<token>')
def activate(token):
    if User.check_activate_token(token):
        flash('账户已激活')
        return redirect(url_for('user.login'))
    else:
        flash('激活失败')
        return redirect(url_for('main.index'))

用户登录认证

  1. 添加登录的跳转链接

  2. 添加登录的视图函数

  3. 添加登录的模板文件

  4. 添加用户登录的表单

  5. 创建登录表单并在模板文件中渲染

  6. 登录检验,如下:

    @user.route('/login/', methods=['GET', 'POST'])
    def login():
        form = LoginForm()
        if form.validate_on_submit():
            u = User.query.filter_by(username=form.username.data).first()
            if not u:
                flash('无效的用户名')
            elif not u.confirmed:
                flash('账户尚未激活,请激活后再登录')
            elif u.r(form.password.data):
                flash('登录成功')
                return redirect(url_for('main.index'))
            else:
                flash('无效的密码')
        return render_template('user/login.html', form=form)
    
  7. flask-login扩展库的使用,如下:

    from flask_login import LoginManager
    login_manager = LoginManager()
    # 初始化对象
    def config_extensions(app):
        ...
        # 登录管理初始化
        login_manager.init_app(app)
        # 指定登录的端点
        login_manager.login_view = 'user.login'
        # 指定登录的提示信息
        login_manager.login_message = '需要登录才可访问'
        # 设置session的保护级别
        # None:用于session保护;'basic':基本的;'strong':最严格的
        # 要想完成记住我的功能,不能设置为'strong'
        login_manager.session_protection = 'strong'
        
    # 定制后就不会默认跳转到登录页面
    @login_manager.unauthorized_handler
    def unauthorized():    
        return 'unauthorized'
    

    另外,需要设置一个回调函数,用户模型继承自UserMixin,如下:

    from flask_login import UserMixin
    
    class User(UserMixin, db.Model):
    	pass
    	
    # 登录认证的回调
    @login_manager.user_loader
    def load_user(uid):
        return User.query.get(int(uid))
    
  8. 使用

    # 登录指定的用户,顺便可以完成'记住我'的功能
    # 可以指定过期时间,timedelta格式
    from datetime import timedelta
    duration = timedelta(seconds=10)
    login_user(u, remember=form.remember.data, duration=duration)
    
  9. 添加不同状态的显示,如下:

    {% if current_user.is_authenticated %}
    	<li><a href="{{ url_for('user.logout') }}">退出</a></li>
    	<li><a href="#">{{ current_user.username }}</a></li>
    {% else %}
    	<li><a href="{{ url_for('user.register') }}">注册</a></li>
    	<li><a href="{{ url_for('user.login') }}">登录</a></li>
    {% endif %}
    
  10. 路由保护

@user.route('/test/')
# 路由保护,需要登录才可访问
@login_required
def test():
    return '登录后才可访问的页面'

登录成功之后的跳转:若get参数中有next则跳转到next位置,没有则跳转到首页

return redirect(request.args.get(‘next’) or url_for(‘main.index’))

  1. flask-login总结

    获取状态:
    	is_authenticated:登录
    	is_anonymous:	匿名
    改变状态:
    	login_user:用户登录,顺便还可以完成'记住我'的功能
    	logout_user:退出登录
    路由保护:保护那些需要登录才有权限访问的路由
    	login_required
    

用户信息管理

  1. 显示用户信息

    1.修改登录后的导航条显示(下拉显示相关操作)
    2.添加用户信息点击的跳转链接
    3.添加对应的视图函数,渲染指定的模板文件
    4.添加用户信息展示的模板文件,显示用户信息(可以参考bootstrap)
    
  2. 修改密码(练习)

  3. 修改邮箱(练习)

  4. 上传头像(练习)
    万水千山总是情,点个关注行不行。
    关注我,看下一篇flask

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值