class TimeStampMixin(object): # Keep track when records are created and updated. time_stamp = datetime.datetime.now(pytz.utc) created_on = db.Column(AwareDateTime(), default=time_stamp) updated_on = db.Column(AwareDateTime(), default=time_stamp, onupdate=time_stamp) def save(self): db.session.add(self) db.session.commit() return self def delete(self): db.session.delete(self) return db.session.commit() def __str__(self): """ Create a human readable version of a class instance. :return: self """ obj_id = hex(id(self)) columns = self.__table__.c.keys() values = ', '.join("%s=%r" % (n, getattr(self, n)) for n in columns) return '<%s %s(%s)>' % (obj_id, self.__class__.__name__, values)
class Region(db.Model, TimeStampMixin): __tablename__ = 'regions' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80), nullable=False) description = db.Column(db.Text) image = db.Column(db.String(250)) parent_id = db.Column(db.Integer) country = db.Column(db.String(20), index=True) state = db.Column(db.String(20), index=True) owner = db.Column(db.Integer, db.ForeignKey('users.id')) wine = db.relationship('Wine', backref=db.backref('wine_region', lazy=True)) @property def serialize(self): return { 'id': self.id, 'name': self.name, 'description': self.description, 'image': self.image, 'parent_id': self.parent_id, 'country': self.country, 'state': self.state, 'created_on': self.created_on, 'updated_on': self.updated_on }
class Comment(db.Model, TimeStampMixin): __tablename__ = 'comments' id = db.Column(db.Integer, primary_key=True) author_id = db.Column(db.Integer, db.ForeignKey('users.id')) text = db.Column(db.Text) image = db.Column(db.String(250)) tnote_id = db.Column(db.Integer, db.ForeignKey('tasting_notes.id')) @property def serialize(self): return { 'id': self.id, 'author_id': self.author_id, 'text': self.text, 'image': self.image, 'tnote_id': self.tnote_id, 'created_on': self.created_on, 'updated_on': self.updated_on }
class User(db.Model, UserMixin, TimeStampMixin): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(50), default='') password = db.Column(db.String(255), default='') email = db.Column(db.String(255), unique=True) first_name = db.Column(db.String(50), nullable=False, default='') last_name = db.Column(db.String(50), nullable=False, default='') display_name = db.Column(db.String(50), default='') image = db.Column(db.String(255)) role = db.Column(db.String(10), server_default='member', index=True) is_enabled = db.Column(db.Boolean(), server_default='True') regions = db.relationship('Region', backref=db.backref('user', lazy=True)) categories = db.relationship('Category', backref=db.backref('user', lazy=True)) wines = db.relationship('Wine', backref=db.backref('user', lazy=True)) tasting_notes = db.relationship('TastingNote', backref=db.backref('user', lazy=True)) comments = db.relationship('Comment', backref=db.backref('user', lazy=True)) @property def serialize(self): return { 'id': self.id, 'username': self.username, 'email': self.email, 'first_name': self.first_name, 'last_name': self.last_name, 'display_name': self.display_name, 'image': self.image, 'role': self.role, 'is_enabled': self.is_enabled, 'created_on': self.created_on, 'updated_on': self.updated_on } def is_active(self): return self.is_enabled def is_admin(self): if self.role == "admin" or INITIAL_ADMIN_SETUP == False: return True else: return False def displayName(self): if self.display_name: return self.display_name elif self.username: return self.username elif self.email: return self.email return None def avatar(self): if self.image: return self.image else: return None def get_comments(self): comments_list = db.session.query(Comment).filter_by( author_id=self.id).all() return comments_list @classmethod def find_by_identity(cls, identity): """ Find a user by their e-mail or username. :param identity: Email or username :type identity: str :return: User instance """ return User.query.filter((User.email == identity) | (User.username == identity)).first() @classmethod def encrypt_password(cls, plaintext_password): """ Hash a plaintext string using PBKDF2. :param plaintext_password: Password in plain text :type plaintext_password: str :return: str """ if plaintext_password: return generate_password_hash(plaintext_password) return None @classmethod def check_password(cls, plaintext_password): """ Hash a plaintext string using PBKDF2. :param plaintext_password: Password in plain text :type plaintext_password: str :return: boolean """ if plaintext_password: hashed_password = generate_password_hash(plaintext_password) if User.password == hashed_password: return True else: return False return False
class TastingNote(db.Model, TimeStampMixin): __tablename__ = 'tasting_notes' id = db.Column(db.Integer, primary_key=True) author_id = db.Column(db.Integer, db.ForeignKey('users.id')) title = db.Column(db.String(80), nullable=False) text = db.Column(db.Text) image = db.Column(db.String(250)) vintage = db.Column(db.String(15)) rating = db.Column(db.Float(12)) price = db.Column(db.Float(12)) likes = db.Column(db.Integer) dlikes = db.Column(db.Integer) wine_id = db.Column(db.Integer, db.ForeignKey('wines.id')) comments = db.relationship('Comment', backref=db.backref('tasting_note', lazy='subquery')) wine = db.relationship('Wine', backref=db.backref('tasting_note', lazy='subquery')) @property def serialize(self): return { 'id': self.id, 'author_id': self.author_id, 'title': self.title, 'text': self.text, 'image': self.image, 'vintage': self.vintage, 'rating': self.rating, 'price': self.price, 'likes': self.likes, 'dlikes': self.dlikes, 'created_on': self.created_on, 'updated_on': self.updated_on }
class Oauth(db.Model, OAuthConsumerMixin): __tablename__ = 'flask_dance_oauth' user_id = db.Column(db.Integer, db.ForeignKey(User.id)) user = db.relationship(User)