from datetime import datetime from flask_sqlalchemy import SQLAlchemy from flask_login import UserMixin from werkzeug.security import generate_password_hash, check_password_hash db = SQLAlchemy() class User(UserMixin, db.Model): """用户模型""" __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, nullable=False, index=True) email = db.Column(db.String(120), unique=True, nullable=False, index=True) password_hash = db.Column(db.String(255), nullable=False) # 学生身份验证 student_id_photo = db.Column(db.String(255)) # 学生证照片路径 is_approved = db.Column(db.Boolean, default=False) # 是否通过审核 # 权限 is_admin = db.Column(db.Boolean, default=False) password_changed = db.Column(db.Boolean, default=True) # 管理员首次登录需修改密码 # 个人信息 bio = db.Column(db.Text) avatar = db.Column(db.String(255)) # 时间戳 created_at = db.Column(db.DateTime, default=datetime.utcnow, index=True) # 关系 posts = db.relationship('Post', backref='author', lazy='dynamic', cascade='all, delete-orphan') comments = db.relationship('Comment', backref='author', lazy='dynamic', cascade='all, delete-orphan') # 关注关系 following = db.relationship( 'Follow', foreign_keys='Follow.follower_id', backref='follower', lazy='dynamic', cascade='all, delete-orphan' ) followers = db.relationship( 'Follow', foreign_keys='Follow.following_id', backref='following', lazy='dynamic', cascade='all, delete-orphan' ) 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 is_following(self, user): """检查是否关注了某用户""" return self.following.filter_by(following_id=user.id).first() is not None def follow(self, user): """关注用户""" if not self.is_following(user): follow = Follow(follower_id=self.id, following_id=user.id) db.session.add(follow) def unfollow(self, user): """取消关注""" follow = self.following.filter_by(following_id=user.id).first() if follow: db.session.delete(follow) def get_follower_count(self): """获取粉丝数""" return self.followers.count() def get_following_count(self): """获取关注数""" return self.following.count() def __repr__(self): return f'' class Post(db.Model): """帖子模型""" __tablename__ = 'posts' id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False, index=True) # 内容 image_path = db.Column(db.String(255), nullable=False) description = db.Column(db.Text) # 审核状态 is_approved = db.Column(db.Boolean, default=False, index=True) # 时间戳 created_at = db.Column(db.DateTime, default=datetime.utcnow, index=True) # 关系 comments = db.relationship('Comment', backref='post', lazy='dynamic', cascade='all, delete-orphan') def get_comment_count(self): """获取评论数""" return self.comments.count() def __repr__(self): return f'' class Comment(db.Model): """评论模型""" __tablename__ = 'comments' id = db.Column(db.Integer, primary_key=True) post_id = db.Column(db.Integer, db.ForeignKey('posts.id'), nullable=False, index=True) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False, index=True) # 内容 content = db.Column(db.Text, nullable=False) # 时间戳 created_at = db.Column(db.DateTime, default=datetime.utcnow, index=True) def __repr__(self): return f'' class Follow(db.Model): """关注关系模型""" __tablename__ = 'follows' id = db.Column(db.Integer, primary_key=True) follower_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False, index=True) following_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False, index=True) created_at = db.Column(db.DateTime, default=datetime.utcnow) # 确保同一用户不能重复关注 __table_args__ = ( db.UniqueConstraint('follower_id', 'following_id', name='unique_follow'), ) def __repr__(self): return f' {self.following_id}>'