flask-web开发中登录和注册功能的实现

本文介绍了在Flask-Web开发中如何实现登录和注册功能。涉及内容包括使用SQLAlchemy构建User和Role模型,通过flask-wtform创建前端表格,以及在app/init.py中设置蓝图和应用初始化。在实现过程中,需注意在app/auth/views.py中正确保存用户信息到数据库。

目录如下:

my_flasky
│  config.py
│  config.pyc
│  data-dev.sqlite
│  manage.py
│
└─app
    │  models.py
    │  models.pyc
    │  __init__.py
    │  __init__.pyc
    │
    ├─auth
    │      forms.py
    │      forms.pyc
    │      views.py
    │      views.pyc
    │      __init__.py
    │      __init__.pyc
    │
    ├─main
    │      views.py
    │      views.pyc
    │      __init__.py
    │      __init__.pyc
    │
    └─templates
        │  base.html
        │  index.html
        │
        └─auth
                login.html
                register.html

要实现登录,注册功能,需要实现的具体功能有:
1,数据库(SQLAlchemy):在app/models中构造User和Role模块,使用时只需要调用,代码如下:

#encoding:utf8
from werkzeug.security import generate_password_hash,check_password_hash
from . import db
from flask_login import UserMixin
from . import login_manager

class Role(db.Model):
    #定义Role的数据库模型
    __tablename__ = 'roles'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    users = db.relationship('User', backref='role', lazy='dynamic')

    def __repr__(self):
        return '<Role %r>' % self.name


class User(db.Model,UserMixin):
    #定义User的数据库模型
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(64), unique=True, index=True)
    username = db.Column(db.String(64), unique=True, index=True)
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
    password_hash = db.Column(db.String(128))  #这里传入的是加密后的密码

    @property
    def password(self):
        #增加密码的不可读属性,防止密码泄露
        raise AttributeError('password is not readable')

    @password.setter
    def password(self,password):
        #将传入的密码进行加密
        self.password_hash = generate_password_hash(password)

    def verify_password(self,password):
        #定义比较密码的方法:传入用户输入的密码,返回bool值
        return check_password_hash(self.password_hash,password)

    def __repr__(self):
        return '<User %r>' % self.username

@login_manager.user_loader
def load_user(user_id):
    #登录状态管理
    return User.query.get(int(user_id))

2,前端表格(wtform):在app/auth/forms.py中使用flask-wtform对前端表格构造,wtforms将前端的东西进行了抽象,我们可以通过python的方法完成前端东西的构造,构造完成之后只需将它用jinja2语法写入模板之中,代码如下:

from flask_wtf import Form
from wtforms import StringField, PasswordField, BooleanField, SubmitField
from wtforms.validators import Required, Length, Email,Regexp,EqualTo
from ..models import User
from wtforms import ValidationError

class LoginForm(Form):
    #登录表格
    email = StringField('Email', validators=[Required(), 
                                        Length(1,64), Email()]) #验证Email格式,长度
    password = PasswordField('Password', validators=[Required()])
    remember_me = BooleanField('Keep me logged in')
    submit = SubmitField('Log In')  


class RegistrationForm(Form):
    #注册表格
    email = StringField('Email', validators=[Required(), Length(1, 64),
                                           Email()])
    username = StringField('Username', validators=[
        Required(), Length(1, 64), Regexp('^[A-Za-z][A-Za-z0-9_.]*$', 0,
                                          'Usernames must have only letters, '
                                          'numbers, dots or underscores')])
    password = PasswordField('Password', validators=[
        Required(), EqualTo('password2', message='Passwords must match.')])
    password2 = PasswordField('Confirm password', validators=[Required()])
    submit = SubmitField('Register')

def validate_email(self, field):
    #定义方法完成与数据库交互,用来判断邮箱是否已经存在
    if User.query.filter_by(email=field.data).first():
        raise ValidationError('Email already registered.')

def validate_username(self, field):
    if User.query.filter_by(username=field.data).first():
        raise ValidationError('Username already in use.')

模板中代码如下app/templates/auth/login.html

{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}

{% block title %}Flasky - Login{% endblock %}

{% block page_content %}
<div class="page-header">
    <h1>Login</h1>
</div>
<div class="col-md-4">
    {{ wtf.quick_form(form) }}
    <br>
    <p>New user? <a href="{{ url_for('auth.register') }}">Click here to register</a>.</p>
</div>
{% endblock %}

app/templates/auth/register.html

{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}

{% block title %}Flasky - Register{% endblock %}

{% block page_content %}
<div class="page-header">
    <h1>Register</h1>
</div>
<div class="col-md-4">
    {{ wtf.quick_form(form) }}
</div>
{% endblock %}

最后,在app/init.py中的create_app中进行蓝图注册,app初始化,代码如下:

#encoding:utf8
from flask import Flask
from flask_bootstrap import Bootstrap
from flask_sqlalchemy import SQLAlchemy
from config import Config
from flask_login import LoginManager

login_manager = LoginManager()
login_manager.session_protection = 'strong'
login_manager.login_views = 'auth.login'

bootstrap = Bootstrap()
db = SQLAlchemy()

def create_app():
app = Flask(__name__)

app.config.from_object(Config)
Config.init_app(app)

#初始化所要用到的模块
login_manager.init_app(app)
bootstrap.init_app(app) 
db.init_app(app)

#从/main/__init__.py中获取蓝图,并注册蓝图
from .main import main as main_blueprint
app.register_blueprint(main_blueprint)
from .auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint)
return app

完成之后先用直接在数据库中插入用户密码,测试登录成功。注册之后显示成功,但是用注册的号进行登录无法成功。原因是在app/auth/views.py中没有对插入数据库的内容进行保存,解决方案是在这里面直接加入

db.session.commit()

或者在配置文件中加入

SQLALCHEMY_COMMIT_ON_TEARDOWN = True
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值