【问题标题】:Flask-Security init: unexpected keyword argument 'password'Flask-Security init:意外的关键字参数“密码”
【发布时间】:2017-10-03 03:31:11
【问题描述】:

努力在我的应用程序中实现Flask-Security。创建默认管理员帐户时出错。我非常密切地关注示例代码,因此对错误的来源感到非常困惑:TypeError: __init__() got an unexpected keyword argument 'password'

__init__.py

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flaskext.markdown import Markdown
from flask_uploads import UploadSet, configure_uploads, IMAGES
from flask_security import Security, SQLAlchemyUserDatastore, utils
from flask_mail import Mail
import private

app = Flask(__name__)
app.config.from_object('settings')
db = SQLAlchemy(app)
mail = Mail(app)

# migrations
migrate = Migrate(app, db)

# markdown
md = Markdown(app, extensions=['fenced_code', 'tables'])

# images
uploaded_images = UploadSet('images', IMAGES)
configure_uploads(app, uploaded_images)

try:
    # importing in a try to avoid import conflict, what's the better way?: 
    from user.models import User, Role    
    # Setup Flask-Security
    user_datastore = SQLAlchemyUserDatastore(db, User, Role)
    security = Security(app, user_datastore)
except Exception as ee:
    pass


from roster import views
from sentence import views
from blog import views
from user import views

@app.before_first_request
def before_first_request():

    # Create the Roles "admin" and "end-user" -- unless they already exist
    user_datastore.find_or_create_role(name='admin', description='Administrator')
    user_datastore.find_or_create_role(name='end-user', description='End user')

    # Create two Users for testing purposes -- unless they already exists.
    # In each case, use Flask-Security utility function to encrypt the password.
    encrypted_password = utils.encrypt_password(private.STARTING_ADMIN_PASS)
    if not user_datastore.get_user('example@gmail.com'):
        user_datastore.create_user(email='example@gmail.com', password=encrypted_password)

    db.session.commit()

    user_datastore.add_role_to_user('example@gmail.com', 'admin')
    db.session.commit()

user.models

from my_app import db
from blog.models import Post
from sentence.models import Sentence
from roster.models import Roster
from datetime import datetime
import datetime
from flask_security import UserMixin, RoleMixin

# Helper table for a many-to-many relationship
roles_users = db.Table('roles_users',
        db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
        db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))

class Role(db.Model, RoleMixin):
    id = db.Column(db.Integer(), primary_key=True)
    name = db.Column(db.String(80), unique=True)
    description = db.Column(db.String(255))

class User(db.Model, UserMixin):
    # general variables
    id = db.Column(db.Integer, primary_key=True)
    first_name = db.Column(db.String(155))
    last_name = db.Column(db.String(155))
    email = db.Column(db.String(255), unique=True)
    password = db.Column(db.String(255))
    active = db.Column(db.Boolean())
    confirmed_at = db.Column(db.DateTime())

    # relations
    roles = db.relationship('Role', secondary=roles_users,
                            backref=db.backref('users', lazy='dynamic'))
    posts = db.relationship('Post', backref='user', lazy='dynamic')
    sentences = db.relationship('Sentence', backref='user', lazy='dynamic')

    def __init__(self, name, email):
        # create a roster
        roster = Roster("default", self.email)
        db.session.add(roster)
        db.session.commit()

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

    # __str__ is required by Flask-Admin (not using?), so we can have human-readable values for the Role when editing a User.
    # If we were using Python 2.7, this would be __unicode__ instead.
    def __str__(self):
        return self.name

    # __hash__ is required to avoid the exception TypeError: unhashable type: 'Role' when saving a User
    def __hash__(self):
        return hash(self.name)

追溯

Traceback (most recent call last):
  File "/home/ubuntu/workspace/my_app/venv/lib/python3.6/site-packages/flask/app.py", line 1994, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/ubuntu/workspace/my_app/venv/lib/python3.6/site-packages/flask/app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "/home/ubuntu/workspace/my_app/venv/lib/python3.6/site-packages/flask/app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/ubuntu/workspace/my_app/venv/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/home/ubuntu/workspace/my_app/venv/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/ubuntu/workspace/my_app/venv/lib/python3.6/site-packages/flask/app.py", line 1607, in full_dispatch_request
    self.try_trigger_before_first_request_functions()
  File "/home/ubuntu/workspace/my_app/venv/lib/python3.6/site-packages/flask/app.py", line 1654, in try_trigger_before_first_request_functions
    func()
  File "/home/ubuntu/workspace/my_app/__init__.py", line 51, in before_first_request
    user_datastore.create_user(email='example@gmail.com', password=encrypted_password)
  File "/home/ubuntu/workspace/my_app/venv/lib/python3.6/site-packages/flask_security/datastore.py", line 167, in create_user
    user = self.user_model(**kwargs)
TypeError: __init__() got an unexpected keyword argument 'password'

【问题讨论】:

    标签: python-3.x flask flask-security


    【解决方案1】:

    如果您查看 Flask-Security 的 datastore.py,您会看到 .create_user() 做了什么:

    def create_user(self, **kwargs):
        """Creates and returns a new user from the given parameters."""
        kwargs = self._prepare_create_user_args(**kwargs)
        user = self.user_model(**kwargs)
        return self.put(user)
    

    它只是试图实例化给定的User 模型。要解决此问题,请调整 User 模型中的 __init__ 方法以处理 password 元素,如下所示:

    def __init__(self, **kwargs):
        self.password = kwargs['password']
        self.email = kwargs['email']
        if kwargs.get('first_name', False):
            self.first_name = kwargs['first_name']
            self.last_name = kwargs['last_name']
        #roster stuff...
    

    【讨论】:

      猜你喜欢
      • 2016-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-07
      • 1970-01-01
      • 2022-12-24
      • 2020-04-15
      相关资源
      最近更新 更多