2017-05-04 5 views
0

Schwierigkeiten zu implementieren Flask-Security innerhalb meiner App. Ich erhalte einen Fehler beim Erstellen von Standardadministratorkonten. Ich folgte Beispiel-Code sehr genau und bin damit sehr verwirrt in Bezug auf die Quelle des Fehlers: TypeError: __init__() got an unexpected keyword argument 'password'Flask-Sicherheit init: unerwartetes Schlüsselwort 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('[email protected]'): 
     user_datastore.create_user(email='[email protected]', password=encrypted_password) 

    db.session.commit() 

    user_datastore.add_role_to_user('[email protected]', '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

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='[email protected]', 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' 
+2

Bitte [Bearbeiten] enthält eine [MCVE]. Was ist die vollständige Rückverfolgung, nicht nur der letzte Fehler? – davidism

+0

Ich frage mich, ob dieser Fehler ein Ergebnis des 'Try:' ist. Sollte mein 'db' Objekt in einer anderen Datei instanziiert werden? Das würde bedeuten, dass ich my_app nicht aus dem Modell importieren müsste. Und wenn ich 'my_app' und damit seine' __init__' Methode nicht benötige, wäre ich in der Lage, user.models innerhalb des '__init__' zu importieren und mich nicht mit' Try :' zu beschäftigen. – dadiletta

+0

Ich habe den Importkonflikt dank [dieser Frage] (http://stackoverflow.com/questions/43812329/python-import-conflict-with-flask-security) behoben. Ich bekomme jedoch immer noch den gleichen Fehler. – dadiletta

Antwort

0

Wenn Sie bei Flask-Security suchen datastore.py können Sie sehen, was .create_user() tut:

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) 

Es einfach versucht, das gegeben User Modell zu instanziiert. Um dies zu beheben, stellen Sie die __init__ Methode in Ihrem User Modell ein password Element zu handhaben wie so:

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... 
Verwandte Themen