class LoginInfo(db.Model): """User Login Info Model.""" __tablename__ = 'login_info' id = db.Column(db.Integer, primary_key=True) user_agent = db.Column(db.String(255), nullable=False) ip_address = db.Column(db.String(255), nullable=False) expires_at = db.Column(db.DateTime, nullable=False) expires_rt = db.Column(db.DateTime, nullable=False) # Access and Refresh Token JTIs jti_at = db.Column(db.String(120), unique=True, nullable=False) jti_rt = db.Column(db.String(120), unique=True, nullable=False) revoked = db.Column(db.Boolean, default=False, nullable=False) # Relations user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) def save_to_db(self): db.session.add(self) db.session.commit() def delete_itself(self): db.session.delete(self) db.session.commit()
class Post(db.Model): id = db.Column(db.Integer, primary_key=True) body = db.Column(db.String(140)) timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow) user_id = db.Column(db.Integer, db.ForeignKey('user.id')) def __repr__(self): return f'<Post {self.body}'
class VisitLog(db.Model): __tablename__ = 'visit_log' id = db.Column(db.Integer, primary_key=True) url = db.Column(db.String(255), nullable=False) method = db.Column(db.String(10)) # GET, POST, PUT, DELETE referrer = db.Column(db.String(255)) platform = db.Column(db.String(80)) browser = db.Column(db.String(80)) version = db.Column(db.String(20)) client_ip = db.Column(db.String(20)) visit_time = db.Column(db.DateTime, default=datetime.datetime.now) people_id = db.Column(db.Integer, db.ForeignKey('people.id', ondelete='SET NULL')) people = db.relationship('People', uselist=False) def __init__(self, url, method, referrer, platform, browser, version, client_ip, visit_time, people_id): self.url = url self.referrer = referrer self.method = method self.platform = platform self.browser = browser self.version = version self.client_ip = client_ip self.visit_time = visit_time self.people_id = people_id
class LoginLog(db.Model): __tablename__ = 'login_log' id = db.Column(db.Integer, primary_key=True) people_id = db.Column(db.Integer, db.ForeignKey(People.id, ondelete='CASCADE'), nullable=True) login_time = db.Column(db.DateTime, default=datetime.datetime.now) login_ip = db.Column(db.String(20)) def __init__(self, people_id, login_ip): self.people_id = people_id self.login_ip = login_ip
class User(UserMixin, db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64), index=True, unique=True) email = db.Column(db.String(120), index=True, unique=True) password_hash = db.Column(db.String(128)) about_me = db.Column(db.String(140)) last_seen = db.Column(db.DateTime, default=datetime.utcnow) def __repr__(self): return f'<User {self.username}>' def set_password(self, password): self.password_hash = generate_password_hash(password) def check_password(self, password): return check_password_hash(self.password_hash, password) def avatar(self, size): digest = md5(self.email.lower().encode('utf-8')).hexdigest() return 'https://www.gravatar.com/avatar/{}?d=identicon&s={}'.format( digest, size)
class PhotoAlbum(db.Model): __tablename__ = 'photo_album' id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(80), nullable=False) description = db.Column(db.Text) people_id = db.Column(db.Integer, db.ForeignKey('people.id', ondelete='CASCADE')) photos = db.relationship('Photo', backref=db.backref('album'), lazy='dynamic') people = db.relationship('People', backref=db.backref('albums', lazy='dynamic')) def __init__(self, title, people_id, description=None): self.title = title self.people_id = people_id self.description = description
class Photo(db.Model): __tablename__ = 'photo' id = db.Column(db.Integer, primary_key=True) uri = db.Column(db.String(255), nullable=False) description = db.Column(db.Text) create_time = db.Column(db.DateTime, default=datetime.datetime.now) album_id = db.Column(db.Integer, db.ForeignKey('photo_album.id', ondelete='SET NULL')) people_id = db.Column(db.Integer, db.ForeignKey('people.id', ondelete='CASCADE')) people = db.relationship('People') def __init__(self, uri, people_id, description=None, album_id=None): self.uri = uri self.description = description self.album_id = album_id self.people_id = people_id def get_uri(self): return render_uri(self.uri) # #class VoiceAlbum(db.Model): # __tablename__ = 'voice_album' # # id = db.Column(db.Integer, primary_key=True) # title = db.Column(db.String(80), nullable=False) # description = db.Column(db.Text) # people_id = db.Column(db.Integer, db.ForeignKey('people.id', ondelete='CASECADE')) #class Voice(db.Model): # __tablename__ = 'voice' # id = db.Column(db.Integer, primary_key=True) # uri = db.Column(db.String(255)) # description = db.Column(db.Text) # create_time = db.Column(db.DateTime, default=datetime.datetime.now) # album_id = db.Column(db.Integer)
class Notification(db.Model): __tablename__ = 'notification' id = db.Column(db.Integer, primary_key=True) from_id = db.Column(db.Integer, db.ForeignKey('people.id', ondelete='SET NULL')) to_id = db.Column(db.Integer, db.ForeignKey('people.id', ondelete='CASCADE')) object_table = db.Column(db.String(20)) object_id = db.Column(db.Integer) content = db.Column(db.String(255)) create_time = db.Column(db.DateTime, default=datetime.datetime.now) has_read = db.Column(db.Boolean, default=False) from_people = db.relationship('People', primaryjoin=(from_id == People.id)) to_people = db.relationship('People', primaryjoin=(to_id == People.id), backref=db.backref('notifications', lazy='dynamic'), passive_deletes=True) def __repr__(self): if self.object_table == 'microblog': obj = Microblog.query.get(self.object_id) pattern = u'<a href="%s">%s</a> 在微博 <a href="%s">%s</a> 中回复了你' return pattern % ( url_for('frontend.people', id=self.from_id), Markup.escape(self.from_people.nickname), url_for('mblog.comment', mid=self.object_id) if obj else '', Markup.escape(obj.content[:20]) if obj else u'抱歉,该微博已删除') elif self.object_table == 'comment': obj = Comment.query.get(self.object_id) pattern = u'<a href="%s">%s</a> 在评论 <a href="%s">%s</a> 中回复了你' return pattern % (url_for('frontend.people', id=self.from_id), Markup.escape(self.from_people.nickname), url_for('mblog.comment', mid=obj.microblog_id, cid=self.object_id) if obj else '', Markup.escape(obj.parent_comment.content[:20]) if obj else u'抱歉,该评论已删除') elif self.object_table == 'photo': obj = Photo.query.get(self.object_id) pattern = u'<a href="%s">%s</a> 在照片 <a href="%s">%s</a> 中回复了你' return pattern % ( url_for('frontend.people', id=self.from_id), Markup.escape(self.from_people.nickname), url_for('photo.show_photo', pid=obj.id, aid=self.album_id) if obj else '', Markup.escape(obj.title[:20]) if obj else u'抱歉,该照片已删除') elif self.object_table == 'album': obj = PhotoAlbum.query.get(self.object_id) pattern = u'<a href="%s">%s</a> 在相册 <a href="%s">%s</a> 中回复了你' return pattern % ( url_for('frontend.people', id=self.from_id), Markup.escape(self.from_people.nickname), url_for('photo.show_album', id=obj.id) if obj else '', Markup.escape(obj.title[:20]) if obj else u'抱歉,该相册已删除') elif self.object_table == 'chatting': pattern = u'<a href="%s">%s</a> 给你发来了一条 <a href="%s">私信</a>' return pattern % (url_for('frontend.people', id=self.from_id), Markup.escape(self.from_people.nickname), url_for('friendship.show_chatting_detail', box='inbox', id=self.object_id)) elif self.object_table == 'friendship': pattern = u'<a href="%s">%s</a> 关注了你' return pattern % ( url_for('frontend.people', id=self.from_id), Markup.escape(self.from_people.nickname), )
class People(db.Model): __tablename__ = 'people' query_class = PeopleQuery id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(80), unique=True, nullable=False) _password = db.Column('password', db.String(80), nullable=False) nickname = db.Column(db.String(20), unique=True) mobile = db.Column(db.String(20)) reg_time = db.Column(db.DateTime, default=datetime.datetime.now) reg_ip = db.Column(db.String(20)) status = db.Column(db.String(10), default='active') avatar = db.Column(db.String(255)) microblogs = db.relationship('Microblog', backref='people', lazy='dynamic', order_by='Microblog.post_time.desc()') comments = db.relationship('Comment', backref='people', lazy='dynamic', order_by='Comment.comment_time') following = db.relationship( 'People', secondary=Friendship, primaryjoin=id == Friendship.c.from_id, secondaryjoin=id == Friendship.c.to_id, backref=db.backref('followed', lazy='dynamic'), lazy='dynamic', ) blocking = db.relationship('People', secondary=Blackship, primaryjoin=id == Blackship.c.from_id, secondaryjoin=id == Blackship.c.to_id, backref=db.backref('blocked', lazy='dynamic'), lazy='dynamic') groups = db.relationship('Group', backref='people', lazy='dynamic', passive_deletes=True) sent_chattings = db.relationship('Chatting', backref='from_people', primaryjoin=id == Chatting.from_id, lazy='dynamic') received_chattings = db.relationship('Chatting', backref='to_people', primaryjoin=id == Chatting.to_id, lazy='dynamic') login_logs = db.relationship( 'LoginLog', backref='people', lazy='dynamic', passive_deletes=True, ) roles = db.relationship('Role', secondary='people_roles') def __init__(self, email, password, nickname=None, mobile=None, reg_time=None, reg_ip=None): self.email = email self._password = hashlib.md5(password).hexdigest() self.nickname = nickname self.mobile = mobile self.reg_time = reg_time self.reg_ip = reg_ip def __repr__(self): return '' # flask.ext.login def is_authenticated(self): return True def is_active(self): return True def is_anonymous(self): return False def get_id(self): return unicode(self.id) # flask.ext.login def is_admin(self): for role in self.roles: if role.name == 'admin': return True return False def get_nickname(self): return self.nickname def get_email(self): return self.email def get_avatar_uri(self): if self.avatar: return render_uri(self.avatar) else: return None def change_password(self, password): self._password = hashlib.md5(password).hexdigest() def change_nickname(self, nickname): self.nickname = nickname def change_mobile(self, mobile): self.mobile = mobile def change_avatar(self, avatar): self.avatar = avatar def is_following(self, id): people = self.following.filter((Friendship.c.from_id == self.id) & (Friendship.c.to_id == id)).first() return True if people else False def is_blocking(self, id): people = self.blocking.filter((Blackship.c.from_id == self.id) & (Blackship.c.to_id == id)).first() return True if people else False def has_group(self, id): group = self.groups.filter_by(id=id).first() return True if group else False def __repr__(self): return self.email def get_mutual(self): return self.followed.filter(Friendship.c.to_id == self.id)
class PeopleInfo(db.Model): __tablename__ = 'people_info' id = db.Column(db.Integer, db.ForeignKey('people.id'), primary_key=True) fullname = db.Column(db.String(20)) gender = db.Column(db.Enum(u'男', u'女')) # 性别,False: Female, True: Male sexual_orientation = db.Column(db.Enum(u'男', u'女')) # 性取向 birthday = db.Column(db.Date) # 生日 age = db.Column(db.SmallInteger) # 年龄,触发器 chinese_zodiac = db.Column( db.Enum(u'鼠', u'牛', u'虎', u'兔', u'龙', u'蛇', u'马', u'羊', u'猴', u'鸡', u'狗', u'猪')) # 生肖,触发器 star_sign = db.Column( db.Enum(u'白羊座', u'金牛座', u'双子座', u'巨蟹座', u'狮子座', u'处女座', u'天秤座', u'天蝎座', u'射手座', u'摩羯座', u'水瓶座', u'双鱼座')) # 星座,触发器 blood_type = db.Column(db.Enum(u'A型', u'B型', u'AB型', u'O型')) # 血型 profession = db.Column(db.String(20)) # 职业 education = db.Column(db.String(20)) # 学历 school = db.Column(db.String(80)) # 毕业院校 homepage = db.Column(db.String(255)) # 个人网站 hometown = db.Column(db.String(20)) # 故乡 location = db.Column(db.String(20)) # 所在地 address = db.Column(db.String(100)) # 地址 zip_code = db.Column(db.String(10)) # 邮编 qq = db.Column(db.String(20)) # QQ 号码 introduction = db.Column(db.Text) # 个人简介 people = db.relationship('People', backref=db.backref('info', uselist=False), uselist=False) def __init__(self, id, fullname, gender, sexual_orientation, birthday, blood_type, profession, education, school, homepage, hometown, location, address, zip_code, qq, introduction): self.id = id self.fullname = fullname self.gender = gender self.sexual_orientation = sexual_orientation self.birthday = birthday self.blood_type = blood_type self.profession = profession self.education = education self.school = school self.homepage = homepage self.hometown = hometown self.location = location self.address = address self.zip_code = zip_code self.qq = qq self.introduction = introduction def change_info(self, fullname, gender, sexual_orientation, birthday, blood_type, profession, education, school, homepage, hometown, location, address, zip_code, qq, introduction): self.fullname = fullname self.gender = gender self.sexual_orientation = sexual_orientation self.birthday = birthday self.blood_type = blood_type self.profession = profession self.education = education self.school = school self.homepage = homepage self.hometown = hometown self.location = location self.address = address self.zip_code = zip_code self.qq = qq self.introduction = introduction def update_age(self): # 计算年龄 pass def update_chinese_zodiac(self): # 计算生肖 pass def update_star_sign(self): # 计算星座 pass
class Role(db.Model): __tablename__ = 'role' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(10))
class Group(db.Model): __tablename__ = 'group' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80), nullable=False) people_id = db.Column(db.Integer, db.ForeignKey('people.id', ondelete='CASCADE'), nullable=False)
class User(db.Model): """Basic user model """ __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(80), unique=True, nullable=False) password = db.Column(db.String(255), nullable=False) active = db.Column(db.Boolean, default=True) attempts = db.Column(db.Integer, nullable=False, server_default=db.text('0')) blocked_until = db.Column(db.DateTime, nullable=True) # Relations login_info = db.relationship(LoginInfo, lazy='dynamic', cascade='all, delete-orphan', backref='user') def __init__(self, **kwargs): super(User, self).__init__(**kwargs) self.password = pwd_context.hash(self.password) def __repr__(self): return "<User %s>" % self.username @classmethod def find_by_email(cls, email): return cls.query.filter_by(email=email).first() @classmethod def find_by_id(cls, _id): return cls.query.filter_by(id=_id).first() @staticmethod def verify_hash(password, _hash): return pwd_context.verify(password, _hash) def save_to_db(self): try: db.session.add(self) db.session.commit() except IntegrityError: db.session.rollback() @staticmethod def generate_fake(count=100): """ Static method to create pool of records in User table in order to work with it """ from sqlalchemy.exc import IntegrityError from random import seed import forgery_py seed() for i in range(count): u = User(email=forgery_py.internet.email_address(), password='******', active=True) db.session.add(u) try: db.session.commit() except IntegrityError: db.session.rollback()