class BaseModel(): """ Generalize __init__, __repr__ and to_json Based on the models columns """ _created_at = db.Column(db.DateTime, nullable=False, default=datetime.now) _updated_at = db.Column(db.DateTime, nullable=True, onupdate=datetime.now) print_filter = () to_json_filter = () non_updatable_column = ("email", "id", "_created_at", "_updated_at") def __repr__(self): """ Define a base way to print models Columns inside `print_filter` are excluded """ return '%s(%s)' % (self.__class__.__name__, { column: value for column, value in self._to_dict().items() if column not in self.print_filter }) def updatable_columns(self) -> List[str]: """ Columns that are valid for updating Columns that starts with _ or rel_, are ignored """ return [ column for column in self._to_dict().keys() if column not in self.non_updatable_column and not column.startswith("_") and not column.startswith("rel_") ] @property def json(self): """ Define a base way to jsonify models Columns that starts with _ or rel_, are ignored """ return { column: value if not isinstance(value, datetime) else value.strftime('%Y-%m-%d') for column, value in self._to_dict().items() if column not in self.to_json_filter and not column.startswith("_") and not column.startswith("rel_") } def _to_dict(self): """ This would more or less be the same as a `to_json` But putting it in a "private" function Allows to_json to be overriden without impacting __repr__ Or the other way around And to add filter lists """ return { column.key: getattr(self, column.key) for column in inspect(self.__class__).attrs } def save(self): db.session.add(self) db.session.commit() return self def delete(self): db.session.delete(self) db.session.commit()
class User(db.Model, BaseModel): __tablename__ = "user" id = db.Column(db.BigInteger, primary_key=True, autoincrement=True) name = db.Column(db.String(255), nullable=False) email = db.Column(db.String(100), unique=True, index=True, nullable=False) _password = db.Column(db.String(128), nullable=False) avatar = db.Column(db.Text, nullable=True) # relationships rel_favorite_movies = db.relationship("FavoriteMovie", cascade="all, delete-orphan", backref="rel_user", lazy="joined") def __init__(self, name, email, password, **kwargs): super(User, self).__init__(**kwargs) """ Create a new User """ self.name = name self.email = email self._password = bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode() self.avatar = kwargs.get("avatar_url", Generator.gravatar_url(self.email)) def __repr__(self): return "User::{}".format(self.id) def check_password(self, password: str): return bcrypt.checkpw(password=password.encode(), hashed_password=self._password.encode())
class FavoriteMovie(db.Model, BaseModel): __tablename__ = "favorite_movie" id = db.Column(db.BigInteger, primary_key=True, autoincrement=True) user_id = db.Column(db.BigInteger, db.ForeignKey("user.id")) imdb_id = db.Column(db.String(20), nullable=False, index=True) def __init__(self, user_id, imdb_id): super(FavoriteMovie, self).__init__() self.user_id = user_id self.imdb_id = imdb_id
class Todo(db.Model, BaseModel): __tablename__ = "todos" id = db.Column(db.BigInteger, primary_key=True, autoincrement=True) title = db.Column(db.String(255), nullable=False) dateline = db.Column(db.DateTime, nullable=True) isCompleted = db.Column(db.Boolean, nullable=True, default=False) def __init__(self, title, dateline, isCompleted, **kwargs): super(Todo, self).__init__(**kwargs) self.title = title self.dateline = dateline self.isCompleted = isCompleted def __repr__(self): return "ToDo({}, {}, {})".format(self.id, self.title, self.isCompleted)
class BaseModel(): """Generalize __init__, __repr__ and to_json Based on the models columns. """ _created_at = db.Column(db.DateTime, nullable=False, default=datetime.now) _updated_at = db.Column(db.DateTime, nullable=False, default=datetime.now) def save(self): db.session.add(self) db.session.commit() return self def delete(self): db.session.delete(self) db.session.commit() def update(self): db.session.commit()
class Todo(db.Model, BaseModel): __tablename__ = "todos" id = db.Column(db.Integer, primary_key=True) text = db.Column(db.String(50)) complete = db.Column(db.Boolean) user_id = db.Column(db.Integer) def __init__(self, text, complete, user_id, **kwargs): super(Todo, self).__init__(**kwargs) self.text = text self.complete = complete self.user_id = user_id def __repr__(self): return f"Todo::{self.id}"
class User(db.Model, BaseModel): __tablename__ = "users" id = db.Column(db.BigInteger, primary_key=True, autoincrement=True) name = db.Column(db.String(255), nullable=False) email = db.Column(db.String(100), unique=True, index=True, nullable=False) _password = db.Column(db.String(128), nullable=False) def __init__(self, name, email, password, **kwargs): super(User, self).__init__(**kwargs) self.name = name self.email = email self._password = bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode() def __repr__(self): return "User({})".format(self.id) def check_password(self, password): return bcrypt.checkpw(password.encode(), self._password.encode())