python - 具有多个用户类的 Flask-Login
问题描述
所以在我的烧瓶项目中,我使用了 Flask-Login 来实现登录/注册系统。然而,这是我的用户表。我还有一个“助推器”表,它具有几乎相同的属性,但更多。例如,助推器将登录到网站的不同部分。我有它的路线分开。所以我的路线是/login、/register 和/booster_login 和/booster_register。我尝试在 booster_login 下的登录方法上使用 login_user 方法,但是当我提交 booster_login 表单时,我得到一个对象没有 is_active 属性。我不能只使用角色,因为助推器将拥有比用户更多的属性。
我的models.py在这里
from flask_login import UserMixin
from flask_sqlalchemy import SQLAlchemy
from flask_admin import Admin
from flask_socketio import SocketIO, join_room
import datetime
db = SQLAlchemy()
socketio = SocketIO()
class User(UserMixin, db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), unique=True)
email = db.Column(db.String(50), unique=True)
password = db.Column(db.String(80))
role = db.Column(db.String(80))
class Booster(db.Model):
id = db.Column(db.Integer, primary_key=True)
booster_name = db.Column(db.String(20), nullable=False)
password = db.Column(db.String(20), nullable=False)
email = db.Column(db.String(50), nullable=False)
join_date = db.Column(db.DateTime(timezone=True))
current_order = db.Column(db.Integer, db.ForeignKey('orders.id'))
current_balance = db.Column(db.Float)
def __init__(self, booster_name, email, password, join_date):
self.booster_name = booster_name
self.password = password
self.email = email
self.join_date = join_date
https://github.com/bshelton/flask-boost/blob/master/views.py
from flask import Flask, render_template, redirect, url_for, Blueprint, request
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
from flask_sqlalchemy import SQLAlchemy, functools
from sqlalchemy import func
from flask_wtf import FlaskForm
#from wtforms import StringField, PasswordField, BooleanField
from passlib.hash import sha256_crypt
from .boostforms import LoginForm, RegisterForm, SoloOrderForm
from .models import User, db, socketio, ChatLog, Orders, join_room, Booster
import datetime
mainbp = Blueprint('mainbp', __name__, template_folder='templates', static_folder='static')
users = {}
@mainbp.route('/')
def index():
return render_template('index.html')
@mainbp.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
submitted_username = form.username.data
submitted_username = str(submitted_username)
submitted_username = submitted_username.lower()
user = User.query.filter(func.lower(User.username)==submitted_username).first()
print (user)
if user:
if user.username.lower() == submitted_username.lower():
if sha256_crypt.verify(form.password.data, user.password) and user.role == "Admin":
login_user(user, remember=form.remember.data)
return redirect(request.args.get('next') or url_for('.admindashboard'))
elif sha256_crypt.verify(form.password.data, user.password) and user.role == "Client":
login_user(user, remember=form.remember.data)
return redirect(request.args.get('next') or url_for('.userdashboard'))
else:
return '<h1> You\'re stupid </h1>'
else:
return '<h1> Invalid Login </h1>'
else:
return '<h1> Invalid Login </h1>'
return render_template('login.html', form=form)
@mainbp.route('/boosterlogin', methods=["GET", "POST"])
def boosterlogin():
form = LoginForm()
if form.validate_on_submit():
submitted_username = form.username.data
submitted_username = str(submitted_username)
submitted_username = submitted_username.lower()
booster = Booster.query.filter(func.lower(Booster.booster_name)==submitted_username).first()
print (booster.booster_name)
if booster:
print (booster.password)
print (form.password.data)
if booster.booster_name.lower() == submitted_username.lower():
if sha256_crypt.verify(form.password.data, booster.password):
login_user(booster, remember=form.remember.data)
return redirect(request.args.get('next') or url_for('.index'))
else:
return '<h1> Wrong Password </h1>'
else:
return '<h1> Invalid Login </h1>'
else:
return '<h1> Invalid Login </h1>'
return render_template('boosterlogin.html', form=form)
@mainbp.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('.index'))
@mainbp.route('/register', methods=['GET', 'POST'])
def register():
form = RegisterForm()
if form.validate_on_submit():
hash_password = sha256_crypt.hash(form.password.data)
new_user = User(username=form.username.data, email=form.email.data, password=hash_password)
db.session.add(new_user)
db.session.commit()
return redirect(url_for('.login'))
return render_template('register.html', form=form)
@mainbp.route('/booster_register', methods=['GET', 'POST'])
def booster_register():
form = RegisterForm()
if form.validate_on_submit():
booster_name = form.username.data
hash_password = sha256_crypt.hash(form.password.data)
email = form.email.data
join_date = datetime.datetime.now()
print ("booster_name: " + booster_name + " password: " + hash_password + " email: " + email)
new_booster = Booster(booster_name=booster_name, email=email, password=hash_password, join_date=datetime.datetime.now())
db.session.add(new_booster)
db.session.commit()
return redirect(url_for('.boosterlogin'))
return render_template('booster_register.html', form=form)
解决方案
当您使用烧瓶登录login()
方法时,它将期望一个UserMixin
实现这些缺失属性的对象。在您的代码中,您仅在 User 模型中实现 UserMixin。尝试让 Booster 从您的User
类继承,如下所示。
class Booster(User):
id = db.Column(db.Integer, primary_key=True)
booster_name = db.Column(db.String(20), nullable=False)
password = db.Column(db.String(20), nullable=False)
email = db.Column(db.String(50), nullable=False)
join_date = db.Column(db.DateTime(timezone=True))
current_order = db.Column(db.Integer, db.ForeignKey('orders.id'))
current_balance = db.Column(db.Float)
def __init__(self, booster_name, email, password, join_date):
self.booster_name = booster_name
self.password = password
self.email = email
self.join_date = join_date
推荐阅读
- ios - UILabel 不显示
- c - 我需要帮助过滤 C 中的坏词吗?
- node.js - 实时服务器上的 NPM 生产和开发
- c# - 是否有一个线性 LINQ 构造用于通过合并两个列表并删除重复项来创建字典
- batch-file - 在 for 循环中变量不会增加
- kentico - How to implement Recaptcha V3 for Kentico?
- javascript - 使用 div 中的标签计数将类添加到每个父 div 中的所有子标签
- python - 为什么 lightgbm 训练出错,显示“特征名称大小错误”?
- python - 我们可以用一条数据线创建散点图吗
- r - 如何按组计算组合列中的值数