class Collect(db.Model): collector_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True) collected_id = db.Column(db.Integer, db.ForeignKey('photo.id'), primary_key=True) timestamp = db.Column(db.DateTime, default=datetime.utcnow) collector = db.relationship('User', back_populates='collections', lazy='joined') collected = db.relationship('Photo', back_populates='collectors', lazy='joined')
class Collect(db.Model): collector_id = db.Column(db.Integer, db.ForeignKey("user.id"), primary_key=True) collected_id = db.Column(db.Integer, db.ForeignKey("photo.id"), primary_key=True) timestamp = db.Column(db.DateTime, default=datetime.utcnow) collector = db.relationship("User", back_populates="collections", lazy="joined") collected = db.relationship("Photo", back_populates="collectors", lazy="joined")
class Follow(db.Model): """连接user, user多对多关系""" follower_id = db.Column(db.Integer, db.ForeignKey("user.id"), primary_key=True) # 关注者 followed_id = db.Column(db.Integer, db.ForeignKey("user.id"), primary_key=True) # 被关注者 follower = db.relationship('User', foreign_keys=[follower_id], back_populates='following', lazy='joined') followed = db.relationship('User', foreign_keys=[followed_id], back_populates='followers', lazy='joined') timestamp = db.Column(db.DateTime, default=datetime.utcnow)
class Follow(db.Model): follower_id = db.Column(db.Integer, db.ForeignKey("user.id"), primary_key=True) followed_id = db.Column(db.Integer, db.ForeignKey("user.id"), primary_key=True) timestamp = db.Column(db.DateTime, default=datetime.utcnow) follower = db.relationship("User", foreign_keys=[follower_id], back_populates="following", lazy="joined") followed = db.relationship("User", foreign_keys=[followed_id], back_populates="followers", lazy="joined")
class Comment(db.Model): """ 评论 """ id = db.Column(db.Integer, primary_key=True) # 内容 body = db.Column(db.Text) # 时间 timestamp = db.Column(db.DateTime, default=datetime.utcnow, index=True) # 举报次数 flag = db.Column(db.Integer, default=0) # 回复 replied_id = db.Column(db.Integer, db.ForeignKey("comment.id")) author_id = db.Column(db.Integer, db.ForeignKey("user.id")) photo_id = db.Column(db.Integer, db.ForeignKey("photo.id")) photo = db.relationship("Photo", back_populates="comments") author = db.relationship("User", back_populates="comments") replies = db.relationship("Comment", back_populates="replied", cascade="all") replied = db.relationship("Comment", back_populates="replies", remote_side=[id])
class Collect(db.Model): '''关联表只能用来表示关系,不能用来存储数据,例如 tagging。 使用关联模型建立多对多关系可以用来存储数据。 ''' collector_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True) collected_id = db.Column(db.Integer, db.ForeignKey('photo.id'), primary_key=True) timestamp = db.Column(db.DateTime, default=datetime.utcnow) # 收藏的时间 collector = db.relationship('User', back_populates='collections', lazy='joined') collected = db.relationship('Photo', back_populates='collectors', lazy='joined')
class Rate(db.Model): id = db.Column(db.Integer, primary_key=True) rate_value = db.Column(db.Integer(), default=0) timestamp = db.Column(db.DateTime, default=datetime.utcnow) rater_photo_id = db.Column(db.Integer, db.ForeignKey('photo.id')) awarded_id = db.Column(db.Integer, db.ForeignKey('user.id')) rater_photo = db.relationship('Photo', foreign_keys=[rater_photo_id], back_populates='rates') awarded = db.relationship('User', foreign_keys=[awarded_id], back_populates='awards')
class Comment(db.Model): id = db.Column(db.Integer, primary_key=True) body = db.Column(db.Text) timestamp = db.Column(db.DateTime, default=datetime.utcnow, index=True) flag = db.Column(db.Integer, default=0) replied_id = db.Column(db.Integer, db.ForeignKey('comment.id')) author_id = db.Column(db.Integer, db.ForeignKey('user.id')) photo_id = db.Column(db.Integer, db.ForeignKey('photo.id')) photo = db.relationship('Photo', back_populates='comments') author = db.relationship('User', back_populates='comments') replies = db.relationship('Comment', back_populates='replied', cascade='all') replied = db.relationship('Comment', back_populates='replies', remote_side=[id])
class Notification(db.Model): id = db.Column(db.Integer, primary_key=True) message = db.Column(db.Text) is_read = db.Column(db.Boolean, default=False) timestamp = db.Column(db.DateTime, default=datetime.utcnow, index=True) receiver_id = db.Column(db.Integer, db.ForeignKey('user.id')) receiver = db.relationship('User', back_populates='notifications')
class Photo(db.Model): id = db.Column(db.Integer, primary_key=True) # 描述 description = db.Column(db.String(500)) # 文件名 filename = db.Column(db.String(64)) # 小图 filename_s = db.Column(db.String(64)) # 中图 filename_m = db.Column(db.String(64)) # 时间 timestamp = db.Column(db.DateTime, default=datetime.utcnow, index=True) # 是否可评论 can_comment = db.Column(db.Boolean, default=True) # 被举报次数 flag = db.Column(db.Integer, default=0) # 用户 author_id = db.Column(db.Integer, db.ForeignKey("user.id")) author = db.relationship("User", back_populates="photos") # 评论 comments = db.relationship("Comment", back_populates="photo", cascade="all") # 收藏 collectors = db.relationship("Collect", back_populates="collected", cascade="all") tags = db.relationship("Tag", secondary=tagging, back_populates="photos")
class Photo(db.Model): id = db.Column(db.Integer, primary_key=True) description = db.Column(db.String(500)) filename = db.Column(db.String(64)) filename_s = db.Column(db.String(64)) filename_m = db.Column(db.String(64)) timestamp = db.Column(db.DateTime, default=datetime.utcnow, index=True) can_comment = db.Column(db.Boolean, default=True) flag = db.Column(db.Integer, default=0) author_id = db.Column(db.Integer, db.ForeignKey('user.id')) rates = db.relationship( 'Rate', foreign_keys=[Rate.rater_photo_id], back_populates='rater_photo', cascade='all', lazy='dynamic') # get the rate data that are given by this photo user author = db.relationship('User', back_populates='photos') comments = db.relationship('Comment', back_populates='photo', cascade='all') collectors = db.relationship('Collect', back_populates='collected', cascade='all') tags = db.relationship('Tag', secondary=tagging, back_populates='photos') invites = db.relationship('Invite', foreign_keys=[Invite.photo_id], back_populates='photo', cascade='all', lazy='dynamic')
class Photo(db.Model): id = db.Column(db.Integer, primary_key=True) description = db.Column(db.String(500)) filename = db.Column(db.String(64)) filename_s = db.Column(db.String(64)) filename_m = db.Column(db.String(64)) timestamp = db.Column(db.DateTime, default=datetime.utcnow) author_id = db.Column(db.Integer, db.ForeignKey('user.id')) author = db.relationship('User', back_populates='photos') can_comment = db.Column(db.Boolean, default=True) flag = db.Column(db.Integer, default=0) comments = db.relationship('Comment', back_populates='photo', cascade='all') tags = db.relationship('Tag', secondary=tagging, back_populates='photos') collectors = db.relationship('Collect', back_populates='collected', cascade='all')
class Invite(db.Model): # user_id(doctor) has been invited to the photo_id. id = db.Column(db.Integer, primary_key=True) photo_id = db.Column(db.Integer, db.ForeignKey('photo.id')) photo = db.relationship('Photo', foreign_keys=[photo_id], back_populates='invites') user_id = db.Column(db.Integer, db.ForeignKey('user.id')) user = db.relationship('User', foreign_keys=[user_id], back_populates='invites') status = db.Column(db.Boolean, default=False) token_id = db.Column(db.String, nullable=False) created_at = db.Column(db.DateTime, default=datetime.now) updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
class Post(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(60)) body = db.Column(db.Text) timestamp = db.Column(db.DateTime, default=datetime.utcnow, index=True) can_comment = db.Column(db.Boolean, default=True) category_id = db.Column(db.Integer, db.ForeignKey('category.id')) category = db.relationship('Category', back_populates='posts')
class Collect(db.Model): collector_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True) collected_id = db.Column(db.Integer, db.ForeignKey('photo.id'), primary_key=True) timestamp = db.Column(db.DateTime, default=datetime.utcnow) # photo.collectors.collector | photo.collectors获取包含收藏对象的Collect的列表,.collector/collected才会加载对应的用户和图片 # 这样就需要两次select,增加了一次查询,那么通过联结join这样只需要一次查询 # 收藏者 collector = db.relationship('User', back_populates='collections', lazy='joined') # 被收藏图片 collected = db.relationship('Photo', back_populates='collectors', lazy='joined')
class Follow(db.Model): # 两侧都在同一个User模型中,这种关系被称为自引用关系(Self-Referential Many-to-Many Relationship)。 follower_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True, comment='关注者id') followed_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True, comment='被关注者id') timestamp = db.Column(db.DateTime, default=datetime.utcnow) follower = db.relationship('User', foreign_keys=[follower_id], back_populates='following', lazy='joined') followed = db.relationship('User', foreign_keys=[followed_id], back_populates='followers', lazy='joined')
class Photo(db.Model): id = db.Column(db.Integer, primary_key=True) description = db.Column(db.String(500), comment='图片描述') filename = db.Column(db.String(64), comment='文件名') filename_s = db.Column(db.String(64), comment="小尺寸图片文件名") filename_m = db.Column(db.String(64), comment="大尺寸图片文件名") timestamp = db.Column(db.DateTime, default=datetime.utcnow, comment='上传时间') author_id = db.Column(db.Integer, db.ForeignKey('user.id')) author = db.relationship('User', back_populates='photos') tags = db.relationship('Tag', secondary=tagging, back_populates='photos') collectors = db.relationship('Collect', back_populates='collected', cascade='all')
class Photo(db.Model): id = db.Column(db.Integer, primary_key=True) description = db.Column(db.String(500)) filename = db.Column(db.String(64)) filename_s = db.Column(db.String(64)) filename_m = db.Column(db.String(64)) timestamp = db.Column(db.DateTime, default=datetime.utcnow, index=True) can_comment = db.Column(db.Boolean, default=True) flag = db.Column(db.Integer, default=0) author_id = db.Column(db.Integer, db.ForeignKey("user.id")) author = db.relationship("User", back_populates="photos") comments = db.relationship('Comment', back_populates="photo", cascade='all') collectors = db.relationship("Collect", back_populates="collected", cascade='all') tags = db.relationship("Tag", secondary=tagging, back_populates="photos")
class Notification(db.Model): """ 消息提醒 """ id = db.Column(db.Integer, primary_key=True) # 消息内容 message = db.Column(db.Text, nullable=False) # 是否已阅读 is_read = db.Column(db.Boolean, default=False) # 时间 timestamp = db.Column(db.DateTime, default=datetime.utcnow, index=True) # 接收者的id receiver_id = db.Column(db.Integer, db.ForeignKey("user.id")) receiver = db.relationship("User", back_populates="notifications")
class Doctor(db.Model): cv = db.Column(db.String(150)) # the hospital name that doctor works. address = db.Column(db.String(200)) # the address of hospital. speciality = db.Column(db.String(150)) latitude = db.Column(db.String(20), default='35.392426') longitude = db.Column(db.String(20), default='139.476048') status = db.Column( db.String(20), default='BAD' ) # represent status of the latitude and longitude, if it is flase, its values are not exact. acct_id = db.Column(db.String(250)) balance = db.Column(db.Float(), default=0.0) withdraws = db.relationship('WithDraw', back_populates='doctor', cascade='all') id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
class WithDraw(db.Model): id = db.Column(db.Integer, primary_key=True) status = db.Column(db.Boolean, default=False) amount = db.Column(db.Float(), default=0.0) bank_code = db.Column(db.String(255)) branch_code = db.Column(db.String(255)) account_number = db.Column(db.String(255)) additional_bank_info = db.Column(db.Text(1000)) created_at = db.Column(db.DateTime, default=datetime.now) updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now) doctor_id = db.Column(db.Integer, db.ForeignKey('doctor.id')) doctor = db.relationship('Doctor', foreign_keys=[doctor_id], back_populates='withdraws')
class User(db.Model, UserMixin): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(20), unique=True, index=True) email = db.Column(db.String(254), unique=True, index=True) password_hash = db.Column(db.String(128)) name = db.Column(db.String(30)) website = db.Column(db.String(255)) bio = db.Column(db.String(120)) location = db.Column(db.String(50)) member_since = db.Column(db.DateTime, default=datetime.utcnow) avatar_s = db.Column(db.String(64)) avatar_m = db.Column(db.String(64)) avatar_l = db.Column(db.String(64)) avatar_raw = db.Column(db.String(64), default='default.jpg') avatar_raw2 = db.Column(db.String(64), default='default2.jpg') confirmed = db.Column(db.Boolean, default=False) locked = db.Column(db.Boolean, default=False) active = db.Column(db.Boolean, default=True) public_collections = db.Column(db.Boolean, default=True) receive_comment_notification = db.Column(db.Boolean, default=True) receive_follow_notification = db.Column(db.Boolean, default=True) receive_collect_notification = db.Column(db.Boolean, default=True) role_id = db.Column(db.Integer, db.ForeignKey('role.id')) role = db.relationship('Role', back_populates='users') photos = db.relationship('Photo', back_populates='author', cascade='all') comments = db.relationship('Comment', back_populates='author', cascade='all') notifications = db.relationship('Notification', back_populates='receiver', cascade='all') collections = db.relationship('Collect', back_populates='collector', cascade='all') following = db.relationship('Follow', foreign_keys=[Follow.follower_id], back_populates='follower', lazy='dynamic', cascade='all') followers = db.relationship('Follow', foreign_keys=[Follow.followed_id], back_populates='followed', lazy='dynamic', cascade='all') awards = db.relationship('Rate', foreign_keys=[Rate.awarded_id], back_populates='awarded', cascade='all', lazy='dynamic') # added for doctor and patient doctor = db.relationship('Doctor', backref='user', cascade='all, delete-orphan', uselist=False) invites = db.relationship('Invite', foreign_keys=[Invite.user_id], back_populates='user', cascade='all', lazy='dynamic') # patient = db.relationship('Patient',backref = 'user', cascade='all, delete-orphan',uselist=False) def __init__(self, **kwargs): super(User, self).__init__(**kwargs) self.generate_avatar() self.follow(self) # follow self self.set_role() def spec(self): if self.role.name == 'Doctor': return self.doctor elif self.role.name == 'Patient': return self.patient def set_password(self, password): self.password_hash = generate_password_hash(password) def set_role(self): if self.role is None: if self.email == current_app.config['ALBUMY_ADMIN_EMAIL']: self.role = Role.query.filter_by(name='Administrator').first() else: randint = random.randint(1, 2) if randint == 1: self.role = Role.query.filter_by(name='Doctor').first() if randint == 2: self.role = Role.query.filter_by(name='Patient').first() # db.session.commit() def set_role_with_name(self, name): self.role = Role.query.filter_by(name=name).first() # db.session.commit() def validate_password(self, password): return check_password_hash(self.password_hash, password) def follow(self, user): if not self.is_following(user): follow = Follow(follower=self, followed=user) # db.session.add(follow) # db.session.commit() def unfollow(self, user): follow = self.following.filter_by(followed_id=user.id).first() if follow: db.session.delete(follow) db.session.commit() def is_following(self, user): if user.id is None: # when follow self, user.id will be None return False return self.following.filter_by( followed_id=user.id).first() is not None def is_followed_by(self, user): return self.followers.filter_by( follower_id=user.id).first() is not None # def get_rate_rated_by(self,user): # return self.awards.filter_by(rater_id = user.id).first() def get_rate_rated_by(self, photo): return self.awards.filter_by(rater_photo_id=photo.id).first() @property def followed_photos(self): return Photo.query.join(Follow, Follow.followed_id == Photo.author_id).filter( Follow.follower_id == self.id) @property def last_uploaded_photo(self): return Photo.query.filter(Photo.author_id == self.id).order_by( Photo.timestamp.desc()).first() def collect(self, photo): if not self.is_collecting(photo): collect = Collect(collector=self, collected=photo) db.session.add(collect) db.session.commit() def uncollect(self, photo): collect = Collect.query.with_parent(self).filter_by( collected_id=photo.id).first() if collect: db.session.delete(collect) db.session.commit() def is_collecting(self, photo): return Collect.query.with_parent(self).filter_by( collected_id=photo.id).first() is not None def lock(self): self.locked = True self.role = Role.query.filter_by(name='Locked').first() db.session.commit() def unlock(self): self.locked = False self.role = Role.query.filter_by(name='User').first() db.session.commit() def block(self): self.active = False db.session.commit() def unblock(self): self.active = True db.session.commit() def generate_avatar(self): avatar = Identicon() filenames = avatar.generate(text=self.username) self.avatar_s = filenames[0] self.avatar_m = filenames[1] self.avatar_l = filenames[2] # db.session.commit() def tags(self): photos = self.photos ret_tags = [] for photo in photos: tags = photo.tags for tag in tags: if not tag in ret_tags: ret_tags.append(tag) return ret_tags @property def is_admin(self): return self.role.name == 'Administrator' @property def is_active(self): return self.active def can(self, permission_name): permission = Permission.query.filter_by(name=permission_name).first() return permission is not None and self.role is not None and permission in self.role.permissions
class User(db.Model, UserMixin): id = db.Column(db.Integer, primary_key=True) # 资料 username = db.Column(db.String(20), unique=True, index=True, comment="用户名") email = db.Column(db.String(254), unique=True, index=True, comment="邮箱") password_hash = db.Column(db.String(128), comment="密码") name = db.Column(db.String(30), comment="真实姓名") website = db.Column(db.String(255)) bio = db.Column(db.String(120)) location = db.Column(db.String(50), comment="城市") member_since = db.Column(db.DateTime, default=datetime.utcnow, comment="用户加入时间") # 用户状态 confirmed = db.Column(db.Boolean, default=False) role_id = db.Column(db.Integer, db.ForeignKey('role.id')) role = db.relationship( 'Role', back_populates='users') # back_populates是用来取代backref photos = db.relationship('Photo', back_populates='author', cascade='all') # 级联关系设为all,当用户被删除时对应的图片记录也被删除 avatar_s = db.Column(db.String(64), comment="小图") avatar_m = db.Column(db.String(64), comment="中图") avatar_l = db.Column(db.String(64), comment="大图") collections = db.relationship('Collect', back_populates='collector', cascade='all') following = db.relationship('Follow', foreign_keys=[Follow.follower_id], back_populates='follower', lazy='dynamic', cascade='all') followers = db.relationship('Follow', foreign_keys=[Follow.followed_id], back_populates='followed', lazy='dynamic', cascade='all') notifications = db.relationship('Notification', back_populates='receiver', cascade='all') avatar_raw = db.Column(db.String(64), comment='用户上传头像文件原图文件名') receive_comment_notification = db.Column(db.Boolean, default=True) receive_follow_notification = db.Column(db.Boolean, default=True) receive_collect_notification = db.Column(db.Boolean, default=True) show_collections = db.Column(db.Boolean, default=True, comment="收藏仅自己可见") locked = db.Column(db.Boolean, default=False, comment="是否被锁定") active = db.Column(db.Boolean, default=True, comment="封禁和解禁") def __init__(self, **kwargs): super(User, self).__init__(**kwargs) self.set_role() self.generate_avatar() self.follow(self) def set_role(self): if self.role is None: if self.email == current_app.config['ALBUMY_ADMIN_EMAIL']: self.role = Role.query.filter_by(name='Administrator').first() else: self.role = Role.query.filter_by(name='User').first() db.session.commit() def set_password(self, password): self.password_hash = generate_password_hash(password) @property def is_admin(self): return self.role.name == 'Administrator' def can(self, permission_name): permission = Permission.query.filter_by(name=permission_name).first() return permission is not None and self.role is None and permission in self.role.permissions def generate_avatar(self): avatar = Identicon() filenames = avatar.generate(text=self.username) self.avatar_s = filenames[0] self.avatar_m = filenames[1] self.avatar_l = filenames[2] db.session.commit() def collect(self, photo): """ 收藏图片 :param photo: :return: """ if not self.is_collecting(photo): collect = Collect(collector=self, collected=photo) db.session.add(collect) db.session.commit() def uncollect(self, photo): """ 取消收藏图片 :param photo: :return: """ collect = self.collected.filter_by(collected_id=photo.id).first() if collect: db.session.delete(collect) db.session.commit() def is_collecting(self, photo): return self.collected.filter_by( collected_id=photo.id).first() is not None def follow(self, user): if not self.is_following(user): follow = Follow(follower=self, followed=user) db.session.add(follow) db.session.commit() def unfollow(self, user): follow = self.following.filter_by(followed_id=user.id).first() if follow: db.session.delete(follow) db.session.commit() def is_following(self, user): if user.id is None: return False return self.following.filter_by( followed_id=user.id).first() is not None def is_followed_by(self, user): return self.followers.filter_by( follower_id=user.id).first() is not None def follow_self_all(self): for user in User.query.all(): user.follow(user) def lock(self): self.locked = True self.role = Role.query.filter_by(name='Locked').first() db.session.commit() def unlock(self): self.locked = False self.role = Role.query.filter_by(name='User').first() db.session.commit() @property def is_active(self): return self.active def block(self): self.active = False db.session.commit() def unblock(self): self.active = True db.session.commit()
def init_role_permission(): for user in User.query.all(): if user.role is None: if user.email == current_app.config['ALBUMY_ADMIN_EMAIL']: user.role = Role.query.filter_by(name='Administrator').first() else: user.role = Role.query.filter_by(name='User').first() db.session.add(user) db.session.commit() roles_permissions = db.Table( 'roles_permissions', db.Column('role_id', db.Integer, db.ForeignKey('role.id')), db.Column('permission_id', db.Integer, db.ForeignKey('permission.id'))) class Role(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(30), unique=True, comment="角色名称") users = db.relationship('User', back_populates='role') permissions = db.relationship('Permission', secondary=roles_permissions, back_populates='roles') @staticmethod def init_role(): roles_permissions_map = { 'Locked': ['FOLLOW', 'COLLECT'], # 被锁定用户
import os from datetime import datetime from flask import current_app from flask_avatars import Identicon from flask_login import UserMixin from werkzeug.security import generate_password_hash, check_password_hash from albumy.extensions import db, whooshee roles_permissions = db.Table('roles_permissions', db.Column('role_id', db.Integer, db.ForeignKey('role.id')), db.Column('permission_id', db.Integer, db.ForeignKey('permission.id'))) class Permission(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(30), unique=True) roles = db.relationship('Role', secondary=roles_permissions, back_populates='permissions') class Role(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(30), unique=True) users = db.relationship('User', back_populates='role') permissions = db.relationship('Permission', secondary= roles_permissions, back_populates='roles') @staticmethod def init_role(): roles_permissions_map = { 'Locked': ['FOLLOW', 'COLLECT'], 'User': ['FOLLOW', 'COLLECT', 'COMMENT', 'UPLOAD'], 'Moderator': ['FOLLOW', 'COLLECT', 'COMMENT', 'UPLOAD', 'MODERATE'], 'Administrator': ['FOLLOW', 'COLLECT', 'COMMENT', 'UPLOAD', 'MODERATE', 'ADMINISTER'] }
class User(db.Model, UserMixin): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(20), unique=True, index=True) email = db.Column(db.String(254), unique=True, index=True) password_hash = db.Column(db.String(128)) name = db.Column(db.String(30)) website = db.Column(db.String(255)) bio = db.Column(db.String(120)) location = db.Column(db.String(50)) member_since = db.Column(db.DateTime, default=datetime.utcnow) avatar_s = db.Column(db.String(64)) avatar_m = db.Column(db.String(64)) avatar_l = db.Column(db.String(64)) avatar_raw = db.Column(db.String(64)) confirmed = db.Column(db.Boolean, default=False) #认证过的用户 locked = db.Column(db.Boolean, default=False) #被限制的用户 active = db.Column(db.Boolean, default=True) #激活的用户 public_collections = db.Column(db.Boolean, default=True) receive_comment_notification = db.Column(db.Boolean, default=True) receive_follow_notification = db.Column(db.Boolean, default=True) receive_collect_notification = db.Column(db.Boolean, default=True) role_id = db.Column(db.Integer, db.ForeignKey('role.id')) role = db.relationship('Role', back_populates='users') photos = db.relationship('Photo', back_populates='author', cascade='all') comments = db.relationship('Comment', back_populates='author', cascade='all') notifications = db.relationship('Notification', back_populates='receiver', cascade='all') collections = db.relationship('Collect', back_populates='collector', cascade='all') following = db.relationship('Follow', foreign_keys=[Follow.follower_id], back_populates='follower', lazy='dynamic', cascade='all') followers = db.relationship('Follow', foreign_keys=[Follow.followed_id], back_populates='followed', lazy='dynamic', cascade='all') def __init__(self, **kwargs): super(User, self).__init__(**kwargs) self.generate_avatar() self.follow(self) # follow self self.set_role() def set_password(self, password): self.password_hash = generate_password_hash(password) def set_role(self): if self.role is None: if self.email == current_app.config['ALBUMY_ADMIN_EMAIL']: self.role = Role.query.filter_by(name='Administrator').first() else: self.role = Role.query.filter_by(name='User').first() db.session.commit() def validate_password(self, password): return check_password_hash(self.password_hash, password) def follow(self, user): if not self.is_following(user): follow = Follow(follower=self, followed=user) db.session.add(follow) db.session.commit() def unfollow(self, user): follow = self.following.filter_by(followed_id=user.id).first() if follow: db.session.delete(follow) db.session.commit() def is_following(self, user): if user.id is None: # when follow self, user.id will be None return False return self.following.filter_by( followed_id=user.id).first() is not None def is_followed_by(self, user): return self.followers.filter_by( follower_id=user.id).first() is not None # @property装饰器来创建只读属性,@property装饰器会将方法转换为相同名称的只读属性,可以与所定义的属性配合使用,这样可以防止属性被修改。 # 调用的时候使用.followed_photos,后面不能加() @property def followed_photos(self): return Photo.query.join(Follow, Follow.followed_id == Photo.author_id).filter( Follow.follower_id == self.id) def collect(self, photo): if not self.is_collecting(photo): collect = Collect(collector=self, collected=photo) db.session.add(collect) db.session.commit() def uncollect(self, photo): collect = Collect.query.with_parent(self).filter_by( collected_id=photo.id).first() if collect: db.session.delete(collect) db.session.commit() def is_collecting(self, photo): return Collect.query.with_parent(self).filter_by( collected_id=photo.id).first() is not None def lock(self): self.locked = True self.role = Role.query.filter_by(name='Locked').first() db.session.commit() def unlock(self): self.locked = False self.role = Role.query.filter_by(name='User').first() db.session.commit() def block(self): self.active = False db.session.commit() def unblock(self): self.active = True db.session.commit() def generate_avatar(self): avatar = Identicon() filenames = avatar.generate(text=self.username) self.avatar_s = filenames[0] self.avatar_m = filenames[1] self.avatar_l = filenames[2] db.session.commit() @property def is_admin(self): return self.role.name == 'Administrator' @property def is_active(self): return self.active # 添can()方法,获取用户的操作权限 def can(self, permission_name): permission = Permission.query.filter_by(name=permission_name).first() return permission is not None and self.role is not None and permission in self.role.permissions
class User(db.Model, UserMixin, ModelMixin): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(20), unique=True, index=True) email = db.Column(db.String(254), unique=True, index=True) password_hash = db.Column(db.String(128)) name = db.Column(db.String(30)) website = db.Column(db.String(255)) bio = db.Column(db.String(120)) location = db.Column(db.String(50)) member_since = db.Column(db.DateTime, default=datetime.utcnow) confirmed = db.Column(db.Boolean, default=False) locked = db.Column(db.Boolean, default=False) active = db.Column(db.Boolean, default=True) avatar_s = db.Column(db.String(64)) avatar_m = db.Column(db.String(64)) avatar_l = db.Column(db.String(64)) avatar_raw = db.Column(db.String(64)) public_collections = db.Column(db.Boolean, default=True) receive_comment_notification = db.Column(db.Boolean, default=True) receive_follow_notification = db.Column(db.Boolean, default=True) receive_collect_notification = db.Column(db.Boolean, default=True) role_id = db.Column(db.Integer, db.ForeignKey('role.id')) role = db.relationship('Role', back_populates='users') photos = db.relationship('Photo', back_populates='author', cascade='all') comments = db.relationship('Comment', back_populates='author', cascade='all') collections = db.relationship('Collect', back_populates='collector', cascade='all') following = db.relationship('Follow', foreign_keys=[Follow.follower_id], back_populates='follower', lazy='dynamic', cascade='all') followers = db.relationship('Follow', foreign_keys=[Follow.followed_id], back_populates='followed', lazy='dynamic', cascade='all') notifications = db.relationship('Notification', back_populates='receiver', cascade='all') token = db.Column(db.String(30), nullable=True) expire_time = db.Column(db.String(255), nullable=True) def __init__(self, **kwargs): super(User, self).__init__(**kwargs) self.generate_avatar() self.set_role() self.follow(self) def set_password(self, password): self.password_hash = generate_password_hash(password) def validate_password(self, password): return check_password_hash(self.password_hash, password) def set_role(self): if self.role is None: if self.email == current_app.config['ALBUMY_ADMIN_EMAIL']: self.role = Role.query.filter_by(name='Administrator').first() else: self.role = Role.query.filter_by(name='User').first() db.session.commit() def generate_avatar(self): avatar_path = os.path.join(current_app.config['ALBUMY_UPLOAD_PATH'], 'avatars') if not os.path.exists(avatar_path): os.mkdir(avatar_path) avatar = Identicon() filenames = avatar.generate(text=self.username) self.avatar_s = filenames[0] self.avatar_m = filenames[1] self.avatar_l = filenames[2] db.session.commit() @property def is_admin(self): return self.role.name == 'Administrator' def can(self, permission_name): permission = Permission.query.filter_by(name=permission_name).first() return permission is not None and self.role is not None and permission in self.role.permissions def is_collecting(self, photo): return Collect.query.with_parent(self).filter_by( collected_id=photo.id).first() is not None def collect(self, photo): if not self.is_collecting(photo): collect = Collect(collector=self, collected=photo) db.session.add(collect) db.session.commit() def uncollect(self, photo): collect = Collect.query.with_parent(self).filter_by( collected_id=photo.id).first() if collect: db.session.delete(collect) db.session.commit() # 是否关注了某个用户 def is_following(self, user): if user.id is None: return False return self.following.filter_by( followed_id=user.id).first() is not None # 是否被某个用户关注 def is_followed_by(self, user): return self.followers.filter_by( follower_id=user.id).first() is not None def follow(self, user): if not self.is_following(user): follow = Follow(follower=self, followed=user) db.session.add(follow) db.session.commit() def unfollow(self, user): follow = self.following.filter_by(followed_id=user.id).first() if follow: db.session.delete(follow) db.session.commit() def lock(self): self.locked = True self.role = Role.query.filter_by(name='Locked').first() db.session.commit() def unlock(self): self.locked = False self.role = Role.query.filter_by(name='User').first() db.session.commit() @property def is_active(self): return self.active def block(self): self.active = False db.session.commit() def unblock(self): self.active = True db.session.commit()
class User(db.Model, UserMixin): """用户""" id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(20), unique=True, index=True) email = db.Column(db.String(254), unique=True, index=True) password_hash = db.Column(db.String(128)) name = db.Column(db.String(30)) website = db.Column(db.String(255)) bio = db.Column(db.String(120)) location = db.Column(db.String(50)) member_since = db.Column(db.DateTime, default=datetime.utcnow) avatar_s = db.Column(db.String(64)) avatar_m = db.Column(db.String(64)) avatar_l = db.Column(db.String(64)) confirmed = db.Column(db.Boolean, default=False) # role role_id = db.Column(db.Integer, db.ForeignKey('role.id')) role = db.relationship('Role', back_populates='users') # own photos photos = db.relationship('Photo', back_populates='author', cascade='all') # comments comments = db.relationship('Comment', back_populates='author', cascade='all') # collect photos collections = db.relationship('Collect', back_populates='collector', cascade='all') # follow following = db.relationship("Follow", foreign_keys=[Follow.follower_id], back_populates='follower', lazy='dynamic', cascade='all') followers = db.relationship("Follow", foreign_keys=[Follow.followed_id], back_populates='followed', lazy='dynamic', cascade='all') # notification notifications = db.relationship('Notification', back_populates='receiver', cascade='all') def __init__(self, **kwargs): super(User, self).__init__(**kwargs) self.set_role() self.generate_avatars() self.follow(self) def generate_avatars(self): avatar = Identicon() filenames = avatar.generate(text=self.username) self.avatar_s, self.avatar_m, self.avatar_l = filenames db.session.commit() def set_role(self): """设置角色""" if self.role: return if self.email == current_app.config['ALBUMY_ADMIN_EMAIL']: self.role = Role.query.filter_by(name='Administrator').first() else: self.role = Role.query.filter_by(name='User').first() db.session.commit() def can(self, permission_name): """验证权限""" permission = Permission.query.filter_by(name=permission_name).first() return permission is not None and self.role is not None and permission in self.role.permissions @property def is_admin(self): return self.role.name == 'Administrator' def set_password(self, password): self.password_hash = generate_password_hash(password) def validate_password(self, password): return check_password_hash(self.password_hash, password) @property def followed_photos(self): return Photo.query.join(Follow, Follow.followed_id == Photo.author_id).filter(Follow.follower_id == self.id) def collect(self, photo): """收藏图片""" if self.is_collecting(photo): return collect = Collect(collector=self, collected=photo) db.session.add(collect) db.session.commit() def uncollect(self, photo): """取消收藏""" collect = Collect.query.with_parent(self).filter_by(collected_id=photo.id).first() if collect: db.session.delete(collect) db.session.commit() def is_collecting(self, photo): """图片是否已收藏""" return Collect.query.with_parent(self).filter_by(collected_id=photo.id).first() is not None def follow(self, user): if self.is_following(user): return follow = Follow(follower=self, followed=user) db.session.add(follow) db.session.commit() def unfollow(self, user): follow = self.following.filter_by(followed_id=user.id).first() if follow: db.session.delete(follow) db.session.commit() def is_following(self, user): # 创建用户后用户首先会关注自身,因为还没有提交数据库会话, user.id will be None if user.id is None: return False return self.following.filter_by(followed_id=user.id).first() is not None def is_followed_by(self, user): return self.followers.filter_by(follower_id=user.id).first() is not None
class User(db.Model, UserMixin): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(20), unique=True, index=True) email = db.Column(db.String(254), unique=True, index=True) password_hash = db.Column(db.String(128)) name = db.Column(db.String(30)) website = db.Column(db.String(255)) bio = db.Column(db.String(120)) location = db.Column(db.String(50)) member_since = db.Column(db.DateTime, default=datetime.utcnow) avatar_s = db.Column(db.String(64)) avatar_m = db.Column(db.String(64)) avatar_l = db.Column(db.String(64)) avatar_raw = db.Column(db.String(64)) confirmed = db.Column(db.Boolean, default=False) locked = db.Column(db.Boolean, default=False) active = db.Column(db.Boolean, default=True) public_collections = db.Column(db.Boolean, default=True) receive_comment_notification = db.Column(db.Boolean, default=True) receive_follow_notification = db.Column(db.Boolean, default=True) receive_collect_notification = db.Column(db.Boolean, default=True) role_id = db.Column(db.Integer, db.ForeignKey("role.id")) role = db.relationship("Role", back_populates="users") photos = db.relationship("Photo", back_populates="author", cascade="all") comments = db.relationship("Comment", back_populates="author", cascade="all") notifications = db.relationship("Notification", back_populates="receiver", cascade="all") collections = db.relationship("Collect", back_populates="collector", cascade="all") following = db.relationship("Follow", back_populates="follower", foreign_keys=[Follow.follower_id], lazy="dynamic", cascade="all") followers = db.relationship("Follow", back_populates="followed", foreign_keys=[Follow.followed_id], lazy="dynamic", cascade="all") def __init__(self, **kwargs): super(User, self).__init__(**kwargs) self.set_role() self.follow(self) self.generate_avatar() def set_password(self, password): self.password_hash = generate_password_hash(password) def set_role(self): if self.role is None: if self.email == current_app.config["ALBUMY_ADMIN_EMAIL"]: self.role = Role.query.filter_by(name="Administrator").first() else: self.role = Role.query.filter_by(name="User").first() db.session.commit() def validate_password(self, password): return check_password_hash(self.password_hash, password) def follow(self, user): if not self.is_following(user): follow = Follow(follower=self, followed=user) db.session.add(follow) db.session.commit() def unfollow(self, user): follow = self.following.filter_by(followed_id=user.id).first() if follow: db.session.delete(follow) db.session.commit() def is_following(self, user): if user.id is None: return False return self.following.filter_by(followed_id=user.id).first() is not None def is_followed_by(self, user): return self.followers.filter_by(follower_id=user.id).first() is not None @property def followed_photo(self): return Photo.query.join(Follow, Follow.followed_id == Photo.author_id).filter(Follow.follower_id == self.id) @property def is_active(self): return self.active def collect(self, photo): if not self.is_collecting(photo): collect = Collect(collector=self, collected=photo) db.session.add(collect) db.session.commit() def uncollect(self, photo): collect = Collect.query.with_parent(self).filter_by(collected_id=photo.id).first() if collect: db.session.delete(collect) db.session.commit() def is_collecting(self, photo): return Collect.query.with_parent(self).filter_by(collected_id=photo.id).first() is not None def generate_avatar(self): avatar = Identicon() filenames = avatar.generate(text=self.username) self.avatar_s = filenames[0] self.avatar_m = filenames[1] self.avatar_l = filenames[2] db.session.commit() def is_admin(self): return self.role.name == "Administrator" def can(self, permission_name): permission = Permission.query.filter_by(name=permission_name).first() return permission is not None and self.role is not None and permission in self.role.permissions def lock(self): self.locked = True self.role = Role.query.filter_by(name="Locked").first() db.session.commit() def unlock(self): self.locked = False self.role = Role.query.filter_by(name="User").first() db.session.commit() def block(self): self.active = False db.session.commit() def unlock(self): self.active = True db.session.commit()
import os from datetime import datetime from flask import current_app from flask_login import UserMixin from werkzeug.security import generate_password_hash, check_password_hash from flask_avatars import Identicon from albumy.extensions import db, whooshee # relationship table roles_permissions = db.Table( "roles_permissions", db.Column("role_id", db.Integer, db.ForeignKey("role.id")), db.Column("permission_id", db.Integer, db.ForeignKey("permission.id")) ) class Permission(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(30), unique=True) roles = db.relationship("Role", secondary=roles_permissions, back_populates="permissions") class Role(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(30), unique=True) users = db.relationship("User", back_populates="role") permissions = db.relationship("Permission", secondary=roles_permissions, back_populates="roles")