thread.py 5.2 KB

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