Esempio n. 1
0
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")
Esempio n. 2
0
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')
Esempio n. 3
0
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')
Esempio n. 4
0
class Owenum(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    sku = db.Column(db.String(60))
    yao = db.Column(db.Integer)
    shiji = db.Column(db.Integer)
    owe = db.Column(db.Integer)
    receive_date = db.Column(db.String(60))
    qd = db.Column(db.String(10))
Esempio n. 5
0
class Jxc_rj_201908(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    ck_id = db.Column(db.Integer)
    sku = db.Column(db.String(30))
    sku_id = db.Column(db.Integer)
    date = db.Column(db.String(30))
    sl_qm = db.Column(db.Integer)
    sl0_pf = db.Column(db.Integer)
    sl0_ls = db.Column(db.Integer)
    sl_qc = db.Column(db.Integer)
Esempio n. 6
0
class UserProfile(DeclarePK, BaseModel):
    # 用户个人信息表
    __tablename__ = "alb_user_profile"
    user_id = declare_foreign_key("alb_user")
    nickname = db.Column(db.String(16), default="", index=True)
    age = db.Column(db.Integer, default=0, index=True)
    head_url = db.Column(db.String(120), default="")
    gender = db.Column(db.Integer, default=0)  # 1 男 2 女  0 未设置

    # 真实信息
    name = db.Column(db.String(16), default="")
    address = db.Column(db.String(60), default="")
Esempio n. 7
0
class Ab_jqx_dxl(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    sku = db.Column(db.String(50))
    sku_id = db.Column(db.Integer)
    qc = db.Column(db.Integer)
    hjyear = db.Column(db.String(50))
    hjmn = db.Column(db.String(50))
    ck_id = db.Column(db.String(50))
    qm = db.Column(db.Integer)
    xs_s = db.Column(db.Integer)
    last = db.Column(db.Integer)
    cbj = db.Column(db.Float)
    weidu = db.Column(db.Integer)
    dxl = db.Column(db.Float)
Esempio n. 8
0
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')
Esempio n. 9
0
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")
Esempio n. 10
0
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=role_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']
		}
		for role_name, permissions in roles_permissions_map.items():
			role = Role.query.filter_by(name=role_name).first()
			if not role:
				role = Role(name=role_name)
				db.session.add(role)
				
			role.permissions = []
			for pname in permissions:
				permission = Permission.query.filter_by(name=pname).first()
				if not permission:
					permission = Permission(name=pname)
					db.session.add(permission)
				role.permissions.append(permission)
				
		db.session.commit()
Esempio n. 11
0
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'],  # 被锁定用户
            'User': ['FOLLOW', 'COLLECT', 'COMMENT', 'UPLOAD'],  # 普通用户
            'Moderator':
            ['FOLLOW', 'COLLECT', 'COMMENT', 'UPLOAD', 'MODERATE'],  # 协管员
            'Administrator': [
                'FOLLOW', 'COLLECT', 'COMMENT', 'UPLOAD', 'MODERATE',
                'ADMINISTER'
            ]  # 管理员
        }
        for role_name in roles_permissions_map:
            role = Role.query.filter_by(name=role_name).first()
            if role is None:
                role = Role(name=role_name)
                db.session.add(role)
            role.permissions = []
            for permission_name in roles_permissions_map[role_name]:
                permission = Permission.query.filter_by(
                    name=permission_name).first()
                if permission is None:
                    permission = Permission(name=permission_name)
                    db.session.add(permission)
                role.permissions.append(permission)
            db.session.commit()
Esempio n. 12
0
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')
Esempio n. 13
0
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"]
        }

        for role_name in roles_permissions_map:
            role = Role.query.filter_by(name=role_name).first()
            if role is None:
                role = Role(name=role_name)
                db.session.add(role)
            role.permissions = []
            for permission_name in roles_permissions_map[role_name]:
                permission = Permission.query.filter_by(name=permission_name).first()
                if permission is None:
                    permission = Permission(name=permission_name)
                    db.session.add(permission)
                role.permissions.append(permission)
        db.session.commit()
Esempio n. 14
0
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')
Esempio n. 15
0
class User(DeclarePK, PasswordUserMixin, BaseModel):
    # 用户登录信息,账号 密码等
    # 设置数据库的表名
    __tablename__ = "alb_user"

    # 用户账号,系统自定生成,运行用户修改一次,例如微信号
    user_name = db.Column(db.String(30),
                          unique=True,
                          nullable=False,
                          index=True)
    reset_user_name = db.Column(db.Boolean, default=False)  # 是否已经自定义过用户账号
    email = db.Column(db.String(30), index=True, default="")
    mobile = db.Column(db.String(11), default="", index=True)
    active = db.Column(db.Integer,
                       default=constant.USER_REGISTERED,
                       unique=False)
    last_login = db.Column(db.DateTime, default=dt.now, index=True)
Esempio n. 16
0
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')

    def __repr__(self):
        return '<Permission %r>' % self.name
Esempio n. 17
0
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")
Esempio n. 18
0
class Tag(db.Model):
    """
	图片标签
	"""
    id = db.Column(db.Integer, primary_key=True)
    # 标签名称
    name = db.Column(db.String(64), index=True, unique=True)

    photos = db.relationship("Photo", secondary=tagging, back_populates="tags")
Esempio n. 19
0
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",  # 管理
            ],
        }

        # 遍历
        for role_name in roles_permissions_map:
            # 取出Role对象,如果没有则创建
            role = Role.query.filter_by(name=role_name).first()
            if role is None:
                role = Role(name=role_name)
                db.session.add(role)
            role.permissions = []
            # 遍历每一种角色拥有的权限
            for permission_name in roles_permissions_map[role_name]:
                # 如果该角色在数据表中不存在,则创建
                permission = Permission.query.filter_by(
                    name=permission_name).first()
                if permission is None:
                    permission = Permission(name=permission_name)
                    db.session.add(permission)
                # 追加到Role对象下
                role.permissions.append(permission)
        db.session.commit()
Esempio n. 20
0
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')
Esempio n. 21
0
class Transaction(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    patient_name = db.Column(db.String(250))
    doctor_name = db.Column(db.String(250))
    token_id = db.Column(db.String(250))
    acct_id = db.Column(db.String(250))
    amount = db.Column(db.String(250))
    currency = db.Column(db.String(250))
    balance_transaction = db.Column(db.String(250))
    description = db.Column(db.String(250))
    created_at = db.Column(db.DateTime, default=datetime.now)
    updated_at = db.Column(db.DateTime,
                           default=datetime.now,
                           onupdate=datetime.now)
Esempio n. 22
0
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)
    #用户状态
    confirmed = db.Column(db.Boolean, default=False)
Esempio n. 23
0
class Order_info(db.Model):
    order_id = db.Column(db.Integer, primary_key=True)
    tid = db.Column(db.String(60), index=True, nullable=False)
    delivery_province = db.Column(db.String(60))
    delivery_city = db.Column(db.String(60))
    delivery_district = db.Column(db.String(60))
    receiver_tel = db.Column(db.String(20))
    body = db.Column(db.Text)
    delivery_address = db.Column(db.String(60))
Esempio n. 24
0
class Category(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(30), unique=True)

    posts = db.relationship('Post', back_populates='category')

    # Deleting a category does not delete the article under that category.
    # The articles under this category will be moved to the default category.
    def delete(self):
        default_category = Category.query.get(1)
        posts = self.posts[:]
        for post in posts:
            post.category = default_category
        db.session.delete(self)
        db.session.commit()
Esempio n. 25
0
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)
Esempio n. 26
0
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)
    confirmed = db.Column(db.Boolean, default=False)

    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)
Esempio n. 27
0
class PasswordUserMixin(UserMixin):
    password_hash = db.Column(db.String(128), nullable=True)

    def set_hash_password(self, password, commit=True):
        """
        产生哈希密码
        :param password:
        :param commit:
        :return:
        """
        # 密码

        self.password_hash = bcrypt.generate_password_hash(password)
        if commit:
            self.save()

    def check_password(self, value):
        """
        校验密码
        :param value:
        :return:
        """

        return bcrypt.check_password_hash(self.password_hash, value)

    def generate_auth_token(self, expire=60 * 60 * 24 * 12):
        """
        产生认证token
        :param expire: token过期时间
        :return:
        """
        s = Serializer(current_app.config["SECRET_KEY"], expires_in=expire)
        return s.dumps({"id": self.id}).decode("ascii")

    @property
    def password(self):
        return "无权限"

    @password.setter
    def password(self, password):
        self.set_hash_password(password)
Esempio n. 28
0
class Tag(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(30), index=True, comment='标签名')
    photos = db.relationship('Photo', secondary=tagging, back_populates='tags')
Esempio n. 29
0
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()
Esempio n. 30
0
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