Вопрос:
Я читаю книгу “Flask Web Development” и создаю подобное приложение для flasky (https://github.com/miguelgrinberg/flasky). Я создал модель User:
from flask_login import UserMixin from werkzeug.security import check_password_hash, generate_password_hash from app import db class User(UserMixin, db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True) email = db.Column(db.String(120), unique=True) password_hash = db.Column(db.String) @property def password(self): raise AttributeError(‘password is read-only’) @password.setter def password(self, password): self.password_hash = generate_password_hash(password) def verify_password(self, password): return verify_password_hash(self.password_hash, password) def __init__(self, username, email): self.username = username self.email = email
Теперь в представлении регистрации я делаю:
user = User(email=form.email.data, username=form.username.data, password = form.password.data)
И я получаю следующую ошибку:
TypeError: __init__() got an unexpected keyword argument ‘password’
Как ни странно, проект учебника делает то же самое, см. Https://github.com/miguelgrinberg/flasky/blob/master/app/auth/views.py, в строке 54.
Он работает, когда я это делаю:
user = User(email=form.email.data, username=form.username.data) user.password = form.password.data
Но я хотел бы иметь возможность передать пароль конструктору. По-видимому, flask_sqlalchemy не понимает, что пароль является свойством. Но как это работает в учебнике? Я не могу найти разницы.
Лучший ответ:
Вы перегрузили __init__ но не разрешили пароль:
def __init__(self, username, email): self.username = username self.email = email
Нет необходимости переопределять __init__ поскольку модель SQLAlchemy по умолчанию предоставляет ту, которая уже принимает все поля. Просто удалите декларацию __init__ и все должно работать.
В коде из книги Майкл переопределяет метод __init__, но он принимает все аргументы ключевых слов, и первое, что он делает, пересылает их на супер-конструктор (чтобы сохранить поведение по умолчанию SQLAlchemy.)