models.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # **************************************************************************
  4. # Copyright © 2016 jianglin
  5. # File Name: models.py
  6. # Author: jianglin
  7. # Email: xiyang0807@gmail.com
  8. # Created: 2016-12-15 20:52:07 (CST)
  9. # Last Update:星期三 2017-3-29 21:49:10 (CST)
  10. # By:
  11. # Description:
  12. # **************************************************************************
  13. from datetime import datetime
  14. from flask import current_app
  15. from flask_login import current_user
  16. from flask_maple.models import ModelMixin, ModelTimeMixin, ModelUserMixin
  17. from forums.api.forums.models import Board
  18. from forums.api.user.models import User
  19. from forums.common.models import CommonUserMixin
  20. from forums.extension import db
  21. from forums.count import Count
  22. topic_follower = db.Table(
  23. 'topic_follower',
  24. db.Column('topic_id', db.Integer, db.ForeignKey('topics.id')),
  25. db.Column('follower_id', db.Integer, db.ForeignKey('users.id')))
  26. class Topic(db.Model, ModelMixin):
  27. __tablename__ = 'topics'
  28. CONTENT_TYPE_TEXT = '0'
  29. CONTENT_TYPE_MARKDOWN = '1'
  30. CONTENT_TYPE_ORGMODE = '2'
  31. CONTENT_TYPE = (('0', 'text'), ('1', 'markdown'), ('2', 'org-mode'))
  32. id = db.Column(db.Integer, primary_key=True)
  33. title = db.Column(db.String(81), nullable=False)
  34. content = db.Column(db.Text, nullable=False)
  35. content_type = db.Column(
  36. db.String(10), nullable=False, default=CONTENT_TYPE_MARKDOWN)
  37. created_at = db.Column(
  38. db.DateTime, default=datetime.utcnow(), nullable=False)
  39. updated_at = db.Column(
  40. db.DateTime, default=datetime.utcnow(), onupdate=datetime.utcnow())
  41. is_good = db.Column(db.Boolean, default=False)
  42. is_top = db.Column(db.Boolean, default=False)
  43. author_id = db.Column(
  44. db.Integer, db.ForeignKey(
  45. 'users.id', ondelete="CASCADE"))
  46. author = db.relationship(
  47. User,
  48. backref=db.backref(
  49. 'topics', cascade='all,delete-orphan', lazy='dynamic'),
  50. lazy='joined')
  51. board_id = db.Column(
  52. db.Integer, db.ForeignKey(
  53. 'boards.id', ondelete="CASCADE"))
  54. board = db.relationship(
  55. Board,
  56. backref=db.backref(
  57. 'topics', cascade='all,delete-orphan', lazy='dynamic'),
  58. lazy='joined')
  59. followers = db.relationship(
  60. User,
  61. secondary=topic_follower,
  62. backref=db.backref(
  63. 'following_topics', lazy='dynamic'),
  64. lazy='dynamic')
  65. def is_followed(self, user=None):
  66. if user is None:
  67. user = current_user
  68. return db.session.query(topic_follower).filter(
  69. topic_follower.c.topic_id == self.id,
  70. topic_follower.c.follower_id == user.id).exists()
  71. def is_collected(self, user=None):
  72. if user is None:
  73. user = current_user
  74. return self.collects.filter_by(author_id=user.id).exists()
  75. @property
  76. def newest_reply(self):
  77. return self.replies.order_by('-id').first()
  78. @property
  79. def reply_count(self):
  80. return self.replies.count()
  81. @reply_count.setter
  82. def reply_count(self, value):
  83. return Count.topic_reply_count(self.id, value)
  84. @property
  85. def read_count(self):
  86. return Count.topic_read_count(self.id)
  87. @read_count.setter
  88. def read_count(self, value):
  89. return Count.topic_read_count(self.id, value)
  90. @property
  91. def read_count(self):
  92. return self.replies.count()
  93. def __str__(self):
  94. return self.title
  95. def __repr__(self):
  96. return "<Topic %r>" % self.title
  97. reply_liker = db.Table(
  98. 'reply_liker',
  99. db.Column('reply_id', db.Integer, db.ForeignKey('replies.id')),
  100. db.Column('liker_id', db.Integer, db.ForeignKey('users.id')))
  101. class Reply(db.Model, ModelMixin):
  102. __tablename__ = 'replies'
  103. id = db.Column(db.Integer, primary_key=True)
  104. content = db.Column(db.Text, nullable=False)
  105. created_at = db.Column(
  106. db.DateTime, default=datetime.utcnow(), nullable=False)
  107. updated_at = db.Column(
  108. db.DateTime, default=datetime.utcnow(), onupdate=datetime.utcnow())
  109. topic_id = db.Column(
  110. db.Integer, db.ForeignKey(
  111. 'topics.id', ondelete="CASCADE"))
  112. topic = db.relationship(
  113. Topic,
  114. backref=db.backref(
  115. 'replies', cascade='all,delete-orphan', lazy='dynamic'),
  116. lazy='joined')
  117. author_id = db.Column(db.Integer, db.ForeignKey('users.id'))
  118. author = db.relationship(
  119. User, backref=db.backref(
  120. 'replies', lazy='dynamic'), lazy='joined')
  121. likers = db.relationship(
  122. User,
  123. secondary=reply_liker,
  124. backref=db.backref(
  125. 'like_replies', lazy='dynamic'),
  126. lazy='dynamic')
  127. def is_liked(self, user=None):
  128. if user is None:
  129. user = current_user
  130. return self.likers.filter_by(id=user.id).exists()
  131. def __str__(self):
  132. return self.content[:10]
  133. def __repr__(self):
  134. return "<Topic %r>" % self.content[:10]