class Collection(DateTimeMixin, FindByIdMixin, db.Model): __tablename__ = 'collection' query_class = CachingQuery id = db.Column('id', db.Integer, primary_key=True, autoincrement=True) title = db.Column('title', db.String(60)) description = db.Column('description', db.String(4096)) user_id = db.Column('user_id', db.ForeignKey(u'user.id'), nullable=False, index=True) user_hashid = db.Column('user_hashid', db.String(32)) answers_count = db.Column('answers_count', db.Integer, server_default='0') following_count = db.Column('following_count', db.Integer, server_default='0') answers = db.relationship(u'Answer', secondary='collection_and_answer', backref='collections') comments = db.relationship(u'Comment', backref='collection') user_on_collection = db.relationship(u'UserOnCollection', backref='collection') def __repr__(self): return '<%s %r>' % (self.__class__.__name__, self.title)
class Topic(DateTimeMixin, FindByIdMixin, db.Model): __tablename__ = 'topic' query_class = CachingQuery id = db.Column('id', db.Integer, primary_key=True, autoincrement=True) name = db.Column('name', db.String(60)) description = db.Column('description', db.String(1024)) avatar_url = db.Column('avatar_url', db.String(200)) questions = db.relationship(u'Question', secondary='topic_and_question', backref='topics') user_on_topic = db.relationship(u'UserOnTopic', backref='topic') def __repr__(self): return '<%s %r>' % (self.__class__.__name__, self.name)
class Question(DateTimeMixin, FindByIdMixin, db.Model): __tablename__ = 'question' query_class = CachingQuery id = db.Column('id', db.Integer, primary_key=True, autoincrement=True) answers_update_time = db.Column('answers_update_time', db.DateTime) title = db.Column('title', db.String(500)) excerpt = db.Column('excerpt', db.String(4096)) answer_ids = db.Column('answer_ids', db.Integer) # count cache voteup_count = db.Column('voteup_count', db.Integer, server_default='0') votedown_count = db.Column('votedown_count', db.Integer, server_default='0') answers_count = db.Column('answers_count', db.Integer, server_default='0') following_count = db.Column('following_count', db.Integer, server_default='0') comments_count = db.Column('comments_count', db.Integer, server_default='0') status = db.Column('status', db.String(45)) user_id = db.Column('user_id', db.ForeignKey(u'user.id'), index=True) user_hashid = db.Column('user_hashid', db.String(32)) answers = db.relationship(u'Answer', backref='question') comments = db.relationship(u'Comment', backref='question') _content = db.Column('content', db.LargeBinary) content = blob_unicode('_content') user_on_question = db.relationship(u'UserOnQuestion', backref='question') @property def following_users(self): uoqs = UserOnQuestion.query.filter( db.and_(UserOnQuestion.question_id == self.id, UserOnQuestion.follow == True)).all() return [uoq.user for uoq in uoqs] def __repr__(self): return '<%s %r>' % (self.__class__.__name__, self.title)
class Comment(DateTimeMixin, FindByIdMixin, db.Model): __tablename__ = 'comment' query_class = CachingQuery id = db.Column('id', db.Integer, primary_key=True, autoincrement=True) content = db.Column('content', db.String(4096)) comment_target = db.Column('comment_target', db.String(10)) user_id = db.Column('user_id', db.ForeignKey(u'user.id'), index=True) user_hashid = db.Column('user_hashid', db.String(32)) quote_comment_id = db.Column('quote_comment_id', db.ForeignKey(u'comment.id'), index=True) answer_id = db.Column('answer_id', db.ForeignKey(u'answer.id'), index=True) question_id = db.Column('question_id', db.ForeignKey(u'question.id'), index=True) collection_id = db.Column('collection_id', db.ForeignKey(u'collection.id'), index=True) user_on_comment = db.relationship(u'UserOnComment', backref='comment') reply_comments = db.relationship("Comment", backref=db.backref('quote_comment', remote_side=[id])) # count cache voteup_count = db.Column('voteup_count', db.Integer, server_default='0') @property def voteup_users(self): ops = UserOnComment.query.filter( db.and_( UserOnComment.comment_id == self.id, UserOnComment.vote == VOTE_UP, )).all() return [op.user for op in ops] def __repr__(self): return '<%s %r>' % (self.__class__.__name__, self.content[0:8])
class User(UserOperationMixin, QuestionOperationMixin, AnswerOperationMixin, CollectionOperationMixin, CommentOperationMixin, DateTimeMixin, FindByIdMixin, UserLoginMixin, db.Model): __tablename__ = 'user' query_class = CachingQuery id = db.Column('id', db.Integer, primary_key=True, autoincrement=True) user_hashid = db.Column('user_hashid', db.String(32)) username = db.Column('username', db.String(45), unique=True) name = db.Column('name', db.String(45)) gender = db.Column('gender', db.Integer) description = db.Column('description', db.String(2048)) headline = db.Column('headline', db.String(200)) avatar_url = db.Column('avatar_url', db.String(200)) # count cache voteup_count = db.Column('voteup_count', db.Integer, server_default='0') votedown_count = db.Column('votedown_count', db.Integer, server_default='0') thanks_count = db.Column('thanks_count', db.Integer, server_default='0') answers = db.relationship(u'Answer', backref='user') collections = db.relationship(u'Collection', backref='user') comments = db.relationship(u'Comment', backref='user') questions = db.relationship(u'Question', backref='user') _password = db.Column('password', db.String(100), nullable=False) def _set_password(self, password): self._password = generate_password_hash(password) def _get_password(self): return self._password password = db.synonym("_password", descriptor=property(_get_password, _set_password)) op_on_answers = db.relationship(u'Answer', secondary='user_on_answer', backref='op_by_users') user_on_answer = db.relationship(u'UserOnAnswer', backref='user') op_on_collections = db.relationship(u'Collection', secondary='user_on_collection', backref='op_by_users') user_on_collection = db.relationship(u'UserOnCollection', backref='user') op_on_comments = db.relationship(u'Comment', secondary='user_on_comment', backref='op_by_users') user_on_comment = db.relationship(u'UserOnComment', backref='user') op_on_questions = db.relationship(u'Question', secondary='user_on_question', backref='op_by_users') user_on_question = db.relationship(u'UserOnQuestion', backref='user') op_on_topics = db.relationship(u'Topic', secondary='user_on_topic', backref='op_by_users') user_on_topic = db.relationship(u'UserOnTopic', backref='user') op_on_users = db.relationship(u'User', secondary='user_on_user', primaryjoin=id == UserOnUser.user_id, secondaryjoin=id == UserOnUser.dest_user_id, backref='op_by_users') user_on_dest_user = db.relationship(u'UserOnUser', foreign_keys=[UserOnUser.user_id], backref='user') dest_user_on_user = db.relationship(u'UserOnUser', foreign_keys=[UserOnUser.dest_user_id], backref='dest_user') @staticmethod def get_admin(cls): return User.query.filter(User.id == 1).first_or_404() @staticmethod def get_user_by_hashid(hashid): return User.query.filter(User.user_hashid == hashid).first() def check_password(self, password): assert self._get_password() return check_password_hash(self._get_password(), password) def op_on_answer(self, answer, edit=False): return self._op_on_x(answer, UserOnAnswer, edit=edit) def op_on_collection(self, collection, edit=False): return self._op_on_x(collection, UserOnCollection, edit=edit) def op_on_comment(self, comment, edit=False): return self._op_on_x(comment, UserOnComment, edit=edit) def op_on_question(self, question, edit=False): return self._op_on_x(question, UserOnQuestion, edit=edit) def op_on_topic(self, topic, edit=False): return self._op_on_x(topic, UserOnTopic, edit=edit) def op_on_user(self, user, edit=False): return self._op_on_x(user, UserOnUser, op_fk=UserOnUser.dest_user_id, one_to_many=self.op_on_users, edit=edit) def _op_on_x(self, x_obj, op_table, op_fk=None, one_to_many=None, edit=False): x_name = x_obj.__class__.__name__ if not op_fk: op_fk_name = '%s_id' % x_name.lower() op_fk = getattr(op_table, op_fk_name) if not one_to_many: one_to_many_name = 'op_on_%ss' % x_name.lower() one_to_many = getattr(self, one_to_many_name) op = op_table.query.filter( db.and_(op_table.user_id == self.id, op_fk == x_obj.id)).first() if not op: if edit: one_to_many.append(x_obj) return self._op_on_x(x_obj, op_table, op_fk=op_fk, one_to_many=one_to_many) else: return None else: return op def __repr__(self): return '<%s %r>' % (self.__class__.__name__, self.username)
class Answer(DateTimeMixin, FindByIdMixin, db.Model): __tablename__ = 'answer' query_class = CachingQuery id = db.Column('id', db.Integer, primary_key=True, autoincrement=True) thanks_count = db.Column('thanks_count', db.Integer) excerpt = db.Column('excerpt', db.String(4096)) user_id = db.Column('user_id', db.ForeignKey(u'user.id'), index=True) user_hashid = db.Column('user_hashid', db.String(32)) question_id = db.Column('question_id', db.ForeignKey(u'question.id'), index=True) collection_id = db.Column('collection_id', db.ForeignKey(u'collection.id'), index=True) user_on_answer = db.relationship(u'UserOnAnswer', backref='answer') comments = db.relationship(u'Comment', backref='answer') _content = db.Column('content', db.LargeBinary) content = blob_unicode('_content') # count cache comments_count = db.Column('comments_count', db.Integer, server_default='0') voteup_count = db.Column('voteup_count', db.Integer, server_default='0') votedown_count = db.Column('votedown_count', db.Integer, server_default='0') @property def vote_count(self): return self.voteup_count - self.votedown_count @property def voteup_users(self): ops = UserOnAnswer.query.filter( db.and_( UserOnAnswer.answer_id == self.id, UserOnAnswer.vote == VOTE_UP, )).all() return [op.user for op in ops] @property def votedown_users(self): ops = UserOnAnswer.query.filter( db.and_( UserOnAnswer.answer_id == self.id, UserOnAnswer.vote == VOTE_DOWN, )).all() return [op.user for op in ops] @property def thanked_users(self): ops = UserOnAnswer.query.filter( db.and_( UserOnAnswer.answer_id == self.id, UserOnAnswer.thank == THANK_ON, )).all() return [op.user for op in ops] def __repr__(self): return '<%s %r>' % (self.__class__.__name__, self.id)