Flask Roles AttributeError:'User'对象没有属性'has_roles'

时间:2016-06-05 19:10:26

标签: flask flask-login

我收到以下错误。我认为由于某种原因,我的UserMixin导入不包含@role_required所需的has_role属性。我是否需要使用RoleMixin。有人可以帮忙吗?

Traceback (most recent call last):
  File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask_debugtoolbar/__init__.py", line 125, in dispatch_request
    return view_func(**req.view_args)
  File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask_login.py", line 792, in decorated_view
    return func(*args, **kwargs)
  File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask_user/decorators.py", line 69, in decorated_view
    if not current_user.has_roles(*role_names):
  File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/werkzeug/local.py", line 338, in __getattr__
    return getattr(self._get_current_object(), name)
AttributeError: 'User' object has no attribute 'has_roles'

我的模特

import datetime as dt
from flask_login import UserMixin
from flaskapp.database import Column, Model, SurrogatePK, db
from flaskapp.teams.models import Teams


class User(UserMixin, SurrogatePK, Model):
    """A user of the app."""

    __tablename__ = 'users'
    user_id = Column(db.BigInteger, unique=True, nullable=False)
    first_name = Column(db.String(30), nullable=True)
    last_name = Column(db.String(80), nullable=True)
    email = Column(db.String(80), unique=True, nullable=False)
    isaf_id = Column(db.String(10), nullable=True)
    primary_team_id = Column(db.Integer, db.ForeignKey(Teams.id), nullable=True)
    primary_team = db.relationship('Teams', foreign_keys='User.primary_team_id')
    is_admin = Column(db.Boolean(), default=False)
    created_at = Column(db.DateTime, nullable=False, default=dt.datetime.utcnow)
    roles = db.relationship('Role', secondary='user_roles',
        backref=db.backref('users', lazy='dynamic'))

    def __init__(self, user_id=user_id, first_name=first_name, last_name=last_name, email=email, is_admin=is_admin, **kwargs):
        """if int(user_id) in current_app.config['ADMINS']:
        self.is_admin = True
        else:
            self.is_admin = False"""
        db.Model.__init__(self, user_id=user_id, first_name=first_name, last_name=last_name, email=email, is_admin=is_admin, **kwargs)
        """Create instance."""

    @property
    def full_name(self):
        """Full user name."""
        return '{0} {1}'.format(self.first_name, self.last_name)

    def __repr__(self):
        """Represent instance as a unique string."""
        return '{0} {1}'.format(self.first_name, self.last_name)

# Define Role model
class Role(db.Model):
    role_id = db.Column(db.Integer(), primary_key=True)
    name = db.Column(db.String(50), unique=True)

# Define UserRoles model
class UserRoles(db.Model):
    id = db.Column(db.Integer(), primary_key=True)
    user_id = db.Column(db.Integer(), db.ForeignKey('users.user_id', ondelete='CASCADE'))
    role_id = db.Column(db.Integer(), db.ForeignKey('role.role_id', ondelete='CASCADE'))

创建用户我执行以下操作

@blueprint.route('/callback/<provider>')
def oauth_callback(provider):

    if not current_user.is_anonymous:
        return redirect(url_for('public.home'))
    oauth = OAuthSignIn.get_provider(provider)
    user_id, first_name, last_name, email, is_admin = oauth.callback()
    if user_id is None:
        flash('Authentication failed.')
        return redirect(url_for('public.home'))
    user = User.query.filter_by(user_id=user_id).first()
    if not user:
        User.create(user_id=user_id, first_name=first_name,         last_name=last_name, email=email, is_admin = is_admin)
    user = User.query.filter_by(user_id=user_id).first()

    if is_admin:
        print('is admin')
        admin = Role.query.filter(Role.name == 'admin').first()
        user.roles.append(admin)
        User.query.filter_by(user_id=user_id).update({'is_admin': True})
    else:
        print('is not admin')
        User.query.filter_by(user_id=user_id).update({'is_admin': False})
    login_user(user, True)
    db.session.commit()
    return redirect(url_for('public.home'))

我认为检查用户是管理员

from flask import Blueprint, flash, redirect, render_template, request, url_for
from flask_login import current_user, login_required
from flask_user import roles_required
from flaskapp.events.forms import CreateEventForm
from flaskapp.events.models import Events
from flaskapp.database import db
from datetime import date
from collections import OrderedDict

@blueprint.route('/add_event', methods=['POST', 'GET'])
@login_required
@roles_required('admin')
def add_event():   

1 个答案:

答案 0 :(得分:0)

来自UserMixin

flask_login课程未提供has_roles属性(source)。您可以在User课程中自行提供:

class User(UserMixin, SurrogatePK, Model):
    # ... Everything that you've written so far

    def has_roles(self, *args):
        return set(args).issubset({role.name for role in self.roles})

此外,您可以使用UserMixin类而不是来自flask_login模块,但来自flask_user模块(是的,名称中存在混淆)。后一类确实提供了has_roles方法。在这种情况下,您需要做的就是更改此行

from flask_login import UserMixin

到此:

from flask_user import UserMixin