thread.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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. starter = serializers.SerializerMethodField()
  36. last_poster = serializers.SerializerMethodField()
  37. api = serializers.SerializerMethodField()
  38. url = serializers.SerializerMethodField()
  39. class Meta:
  40. model = Thread
  41. fields = [
  42. "id",
  43. "category",
  44. "title",
  45. "replies",
  46. "has_unapproved_posts",
  47. "started_on",
  48. "starter_name",
  49. "last_post_on",
  50. "last_post_is_event",
  51. "last_post",
  52. "last_poster_name",
  53. "is_unapproved",
  54. "is_hidden",
  55. "is_closed",
  56. "weight",
  57. "best_answer",
  58. "best_answer_is_protected",
  59. "best_answer_marked_on",
  60. "best_answer_marked_by",
  61. "best_answer_marked_by_name",
  62. "best_answer_marked_by_slug",
  63. "acl",
  64. "is_new",
  65. "is_read",
  66. "path",
  67. "poll",
  68. "subscription",
  69. "starter",
  70. "last_poster",
  71. "api",
  72. "url",
  73. ]
  74. def get_acl(self, obj):
  75. try:
  76. return obj.acl
  77. except AttributeError:
  78. return {}
  79. def get_has_unapproved_posts(self, obj):
  80. try:
  81. acl = obj.acl
  82. except AttributeError:
  83. return False
  84. return acl.get("can_approve") and obj.has_unapproved_posts
  85. def get_is_new(self, obj):
  86. try:
  87. return obj.is_new
  88. except AttributeError:
  89. return None
  90. def get_is_read(self, obj):
  91. try:
  92. return obj.is_read
  93. except AttributeError:
  94. return None
  95. def get_participants(self, obj):
  96. return ThreadParticipantSerializer(obj.participants_list, many=True).data
  97. def get_subscription(self, obj):
  98. try:
  99. return obj.subscription.send_email
  100. except AttributeError:
  101. return None
  102. def get_starter(self, obj):
  103. if obj.starter_id:
  104. return {
  105. "id": obj.starter_id,
  106. "username": obj.starter.username,
  107. "real_name": obj.starter.get_real_name(),
  108. "avatars": obj.starter.avatars,
  109. }
  110. def get_last_poster(self, obj):
  111. if obj.last_poster_id:
  112. return {
  113. "id": obj.last_poster_id,
  114. "username": obj.last_poster.username,
  115. "real_name": obj.last_poster.get_real_name(),
  116. "avatars": obj.last_poster.avatars,
  117. }
  118. def get_api(self, obj):
  119. return {
  120. "index": obj.get_api_url(),
  121. "editor": obj.get_editor_api_url(),
  122. "merge": obj.get_merge_api_url(),
  123. "poll": obj.get_poll_api_url(),
  124. "posts": {
  125. "index": obj.get_posts_api_url(),
  126. "merge": obj.get_post_merge_api_url(),
  127. "move": obj.get_post_move_api_url(),
  128. "split": obj.get_post_split_api_url(),
  129. },
  130. }
  131. def get_url(self, obj):
  132. return {
  133. "index": obj.get_absolute_url(),
  134. "new_post": obj.get_new_post_url(),
  135. "last_post": obj.get_last_post_url(),
  136. "best_answer": obj.get_best_answer_url(),
  137. "unapproved_post": obj.get_unapproved_post_url(),
  138. "starter": self.get_starter_url(obj),
  139. "last_poster": self.get_last_poster_url(obj),
  140. }
  141. def get_starter_url(self, obj):
  142. if obj.starter_id:
  143. return reverse(
  144. "misago:user", kwargs={"slug": obj.starter_slug, "pk": obj.starter_id}
  145. )
  146. def get_last_poster_url(self, obj):
  147. if obj.last_poster_id:
  148. return reverse(
  149. "misago:user",
  150. kwargs={"slug": obj.last_poster_slug, "pk": obj.last_poster_id},
  151. )
  152. class PrivateThreadSerializer(ThreadSerializer):
  153. participants = serializers.SerializerMethodField()
  154. class Meta:
  155. model = Thread
  156. fields = ThreadSerializer.Meta.fields + ["participants"]
  157. class ThreadsListSerializer(ThreadSerializer):
  158. category = serializers.PrimaryKeyRelatedField(read_only=True)
  159. last_post = serializers.PrimaryKeyRelatedField(read_only=True)
  160. class Meta:
  161. model = Thread
  162. fields = ThreadSerializer.Meta.fields + ["has_poll"]
  163. ThreadsListSerializer = ThreadsListSerializer.exclude_fields("path", "poll")