无法使用flask-sqlalchemy从多对多关系中检索值

时间:2019-08-11 22:45:38

标签: python sqlalchemy flask-sqlalchemy

我有3个表分别用于user,role和user_role(关联表)。用户和角色可以具有多对多关系。我正在使用has_role()函数,如果用户可以使用所需的角色,则该函数应返回true。 @roles_required装饰器将调用此函数,该装饰器将角色要求作为输入。当我在self.roles函数中使用has_role()打印当前用户的角色时,总是会得到一个空列表。它总是显示用户在使用管理路由时没有所需的角色。

--- models.py

 class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)

    # User authentication information
    username = db.Column(db.String(50), nullable=False, unique=True)
    password = db.Column(db.String(255), nullable=False, server_default='')

    # User email information
    #email = db.Column(db.String(255), nullable=False, unique=True)
    #confirmed_at = db.Column(db.DateTime())

    # User information
    active = db.Column('is_active', db.Boolean(), nullable=False, server_default='0')
    first_name = db.Column(db.String(100), nullable=False, server_default='')
    last_name = db.Column(db.String(100), nullable=False, server_default='')

    # Relationships
    roles = db.relationship('Role', secondary='user_roles',
            backref=db.backref('users', lazy='dynamic

    def has_roles(self, *requirements):
        if hasattr(self, 'roles'):
            roles = self.roles
            print(roles)
        else:
            if hasattr(self, 'user_profile') and hasattr(self.user_profile, 'roles'):
                roles = self.user_profile.roles
            else:
                roles = None
        if not roles: 
            return False

        # Translates a list of role objects to a list of role_names
        user_role_names = [role.name for role in roles]

        # has_role() accepts a list of requirements
        for requirement in requirements:
            if isinstance(requirement, (list, tuple)):
                # this is a tuple_of_role_names requirement
                tuple_of_role_names = requirement
                authorized = False
                for role_name in tuple_of_role_names:
                    if role_name in user_role_names:
                        # tuple_of_role_names requirement was met: break out of loop
                        authorized = True
                        break
                if not authorized:
                    return False                    # tuple_of_role_names requirement failed: return False
            else:
                # this is a role_name requirement
                role_name = requirement
                # the user must have this role
                if not role_name in user_role_names:
                    return False                    # role_name requirement failed: return False

        # All requirements have been met: return True
        return True

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

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

--- resource.py

def roles_required(*role_names):
    def wrapper(func):
        @wraps(func)
        def decorated_view(*args, **kwargs):
            # User must be logged
            current_user=User()

            # User must have the required roles
            if not current_user.has_roles(role_names):
                # Redirect to the unauthorized page
                return "required role not available"

            # Call the actual view
            return func(*args, **kwargs)
        return decorated_view
    return wrapper



    @ns.route('/registration')
class UserRegistration(Resource):
    def post(self):
        data = request.get_json()
        new_user = User(
            username = data['username'],
            password = User.generate_hash(data['password']),
            created_by = data['username'],
            updated_by = data['username']
            )
    new_user.roles.append(Role(name=data['role']))
    new_user.save_to_db()
    access_token = create_access_token(identity = data['username'])
    refresh_token = create_refresh_token(identity = data['username'])
    return {
        'message': 'User {} was created'.format(data['username']),
        'access_token': access_token,
        'refresh_token': refresh_token
        }
@ns.route('/admin')
    class adminpage(Resource):    
        @roles_required('admin')
        def get(self):
            return({'msg':'admins can access only'})

0 个答案:

没有答案