thread.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. from django.urls import reverse
  2. from rest_framework import serializers
  3. from ...categories.serializers import CategorySerializer
  4. from ...core.serializers import MutableFields
  5. from ..models import Thread
  6. from .poll import PollSerializer
  7. from .threadparticipant import ThreadParticipantSerializer
  8. __all__ = ["ThreadSerializer", "PrivateThreadSerializer", "ThreadsListSerializer"]
  9. BasicCategorySerializer = CategorySerializer.subset_fields(
  10. "id",
  11. "parent",
  12. "name",
  13. "short_name",
  14. "color",
  15. "description",
  16. "is_closed",
  17. "css_class",
  18. "level",
  19. "lft",
  20. "rght",
  21. "is_read",
  22. "url",
  23. )
  24. class ThreadSerializer(serializers.ModelSerializer, MutableFields):
  25. category = BasicCategorySerializer(many=False, read_only=True)
  26. acl = serializers.SerializerMethodField()
  27. has_unapproved_posts = serializers.SerializerMethodField()
  28. is_new = serializers.SerializerMethodField()
  29. is_read = serializers.SerializerMethodField()
  30. path = BasicCategorySerializer(many=True, read_only=True)
  31. poll = PollSerializer(many=False, read_only=True)
  32. best_answer = serializers.PrimaryKeyRelatedField(read_only=True)
  33. best_answer_marked_by = serializers.PrimaryKeyRelatedField(read_only=True)
  34. subscription = serializers.SerializerMethodField()
  35. api = serializers.SerializerMethodField()
  36. url = serializers.SerializerMethodField()
  37. class Meta:
  38. model = Thread
  39. fields = [
  40. "id",
  41. "category",
  42. "title",
  43. "replies",
  44. "has_unapproved_posts",
  45. "started_on",
  46. "starter_name",
  47. "last_post_on",
  48. "last_post_is_event",
  49. "last_post",
  50. "last_poster_name",
  51. "is_unapproved",
  52. "is_hidden",
  53. "is_closed",
  54. "weight",
  55. "best_answer",
  56. "best_answer_is_protected",
  57. "best_answer_marked_on",
  58. "best_answer_marked_by",
  59. "best_answer_marked_by_name",
  60. "best_answer_marked_by_slug",
  61. "acl",
  62. "is_new",
  63. "is_read",
  64. "path",
  65. "poll",
  66. "subscription",
  67. "api",
  68. "url",
  69. ]
  70. def get_acl(self, obj):
  71. try:
  72. return obj.acl
  73. except AttributeError:
  74. return {}
  75. def get_has_unapproved_posts(self, obj):
  76. try:
  77. acl = obj.acl
  78. except AttributeError:
  79. return False
  80. return acl.get("can_approve") and obj.has_unapproved_posts
  81. def get_is_new(self, obj):
  82. try:
  83. return obj.is_new
  84. except AttributeError:
  85. return None
  86. def get_is_read(self, obj):
  87. try:
  88. return obj.is_read
  89. except AttributeError:
  90. return None
  91. def get_participants(self, obj):
  92. return ThreadParticipantSerializer(obj.participants_list, many=True).data
  93. def get_subscription(self, obj):
  94. try:
  95. return obj.subscription.send_email
  96. except AttributeError:
  97. return None
  98. def get_api(self, obj):
  99. return {
  100. "index": obj.get_api_url(),
  101. "editor": obj.get_editor_api_url(),
  102. "merge": obj.get_merge_api_url(),
  103. "poll": obj.get_poll_api_url(),
  104. "posts": {
  105. "index": obj.get_posts_api_url(),
  106. "merge": obj.get_post_merge_api_url(),
  107. "move": obj.get_post_move_api_url(),
  108. "split": obj.get_post_split_api_url(),
  109. },
  110. }
  111. def get_url(self, obj):
  112. return {
  113. "index": obj.get_absolute_url(),
  114. "new_post": obj.get_new_post_url(),
  115. "last_post": obj.get_last_post_url(),
  116. "best_answer": obj.get_best_answer_url(),
  117. "unapproved_post": obj.get_unapproved_post_url(),
  118. "starter": self.get_starter_url(obj),
  119. "last_poster": self.get_last_poster_url(obj),
  120. }
  121. def get_starter_url(self, obj):
  122. if obj.starter_id:
  123. return reverse(
  124. "misago:user", kwargs={"slug": obj.starter_slug, "pk": obj.starter_id}
  125. )
  126. def get_last_poster_url(self, obj):
  127. if obj.last_poster_id:
  128. return reverse(
  129. "misago:user",
  130. kwargs={"slug": obj.last_poster_slug, "pk": obj.last_poster_id},
  131. )
  132. class PrivateThreadSerializer(ThreadSerializer):
  133. participants = serializers.SerializerMethodField()
  134. class Meta:
  135. model = Thread
  136. fields = ThreadSerializer.Meta.fields + ["participants"]
  137. class ThreadsListSerializer(ThreadSerializer):
  138. category = serializers.PrimaryKeyRelatedField(read_only=True)
  139. last_post = serializers.PrimaryKeyRelatedField(read_only=True)
  140. starter = serializers.SerializerMethodField()
  141. last_poster = serializers.SerializerMethodField()
  142. class Meta:
  143. model = Thread
  144. fields = ThreadSerializer.Meta.fields + ["has_poll", "starter", "last_poster"]
  145. def get_starter(self, obj):
  146. if obj.starter_id:
  147. return {
  148. "id": obj.starter_id,
  149. "username": obj.starter.username,
  150. "real_name": obj.starter.get_real_name(),
  151. "avatars": obj.starter.avatars,
  152. }
  153. def get_last_poster(self, obj):
  154. if obj.last_poster_id:
  155. return {
  156. "id": obj.last_poster_id,
  157. "username": obj.last_poster.username,
  158. "real_name": obj.last_poster.get_real_name(),
  159. "avatars": obj.last_poster.avatars,
  160. }
  161. ThreadsListSerializer = ThreadsListSerializer.exclude_fields("path", "poll")