如何将用户属性传递给 python function/route -- Flask

How to pass in a user attribute to a python function/route -- Flask

所以我在 Flask 中创建了一个简单的网站,允许两种类型的用户。管理员和普通用户。我有一个名为 "User" 的 class,它有一个属性 "isUser"。然后我有一个路由调用 "addMovie",它接受一个参数 "isUser" 来检查当前用户是否有权添加电影。我该如何检查?截至目前,我将该属性设置为 "Yes" 的用户仍然可以添加电影。

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    first_name = db.Column(db.String(120))
    last_name = db.Column(db.String(120))
    email = db.Column(db.String(180), unique=True)
    password = db.Column(db.String(255))
    isUser = db.Column(db.String(10))
    active = db.Column(db.Boolean())
    confirmed_at = db.Column(db.DateTime())
    roles = db.relationship('Role', secondary=roles_users,backref=db.backref('users', lazy='dynamic'))

@app.route('/addMovie/<isUser>', methods=['GET', 'POST'])
@login_required
def addMovie(isUser):
    error = None
    if(isUser == "Yes"):
        error = "You must have Admin Privaledges to add a Movie/TV Show"
        return redirect(url_for('index'))
    else:
        return render_template('addMovie.html', error=error)

一旦您像这样重新考虑您的模型 class 就会很好...

class User(db.Model, UserMixin)
    is_admin = db.Column(db.Boolean(default=False))

您必须以某种方式在视图函数中获取 user 对象。如果您使用 Flask-login

from flask_login import current_user

if current_user.is_admin:
    return render_template('addMovie.html')
else:
    flash('You must have Admin Privaledges to add a Movie/TV Show')
    return redirect(url_for('index')

或者直接获取对象id

@app.route('/addMovie/<userid>', methods=['GET', 'POST'])
@login_required
def addMovie(userid):
    user = User.query.filter(id=userid).first()

我假设您正在使用 Flask-Login。你试过current_user了吗?

然后您可以检查当前登录的用户是否是管理员。最后在需要管理功能的地方调用此方法。

from flask_login import current_user, login_required, LoginManager

@login_manager.user_loader
def load_user(id):
    return User.query.get(int(id))

def require_admin():
    if current_user.isUser:
        abort(403)

@app.errorhandler(403)
def error_access_forbidden(error):
    error_code = 403
    error_message = "Sorry, access denied or forbidden!"
    return render_template('4xx.html',
                           error_code = error_code,
                           error_message=error_message), 403

@app.route('/addMovie', methods=['GET', 'POST'])
@login_required
def addMovie():
    require_admin()
    error = None
    return render_template('addMovie.html', error=error)

4xx.html 模板可能会显示错误代码、错误消息和重定向链接。这是处理 HTTP 错误的正确方法。您也可以实施其他 HTTP 错误。

这是我在我的项目之一中使用的示例错误页面:

这里有一些要改变的东西,使它更符合 Python 风格:

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    first_name = db.Column(db.String(120))
    last_name = db.Column(db.String(120))
    email = db.Column(db.String(180), unique=True)
    password = db.Column(db.String(255))
    is_admin = db.Column(db.Boolean(), default=False)
    active = db.Column(db.Boolean())
    confirmed_at = db.Column(db.DateTime())
    roles = db.relationship('Role', secondary=roles_users,backref=db.backref('users', lazy='dynamic'))

@app.route('/addMovie/<user_id:int>', methods=['GET', 'POST'])
@admin_required
@login_required
def addMovie(user_id):
    user = db.session.query(User).get(user_id)
    return render_template('addMovie.html', user=user)   

def admin_required(f):
   def decorated(*args, **kwargs):
       if not g.user.is_admin:
         return redirect(url_for('index'))
   return f(*args, **kwargs)
return decorated

当您使用 Flask 的 loging_required 装饰器时,您可以编写自己的 admin_required 并用它包装您的视图。它应该检查您的用户是否有添加文件的权限,如果没有则将他重定向到 index 页面。此外,我已将您的数据库字段更改为 Boolean 类型,因为它更方便。

P.S。此代码段未经测试,可能包含一些错误,但您已经明白了,对吧?