serializers.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. from rest_framework import serializers
  2. from django.urls import reverse
  3. from misago.core.serializers import MutableFields
  4. from misago.core.utils import format_plaintext_for_html
  5. from .models import Category
  6. __all__ = ['CategorySerializer']
  7. def last_activity_detail(f):
  8. """util for serializing last activity details"""
  9. def decorator(self, obj):
  10. if not obj.last_thread_id:
  11. return None
  12. acl = self.get_acl(obj)
  13. if not all((
  14. acl.get('can_see'),
  15. acl.get('can_browse'),
  16. acl.get('can_see_all_threads')
  17. )):
  18. return None
  19. return f(self, obj)
  20. return decorator
  21. class CategorySerializer(serializers.ModelSerializer, MutableFields):
  22. parent = serializers.PrimaryKeyRelatedField(read_only=True)
  23. description = serializers.SerializerMethodField()
  24. is_read = serializers.SerializerMethodField()
  25. subcategories = serializers.SerializerMethodField()
  26. absolute_url = serializers.SerializerMethodField()
  27. last_poster_url = serializers.SerializerMethodField()
  28. last_post_url = serializers.SerializerMethodField()
  29. last_thread_url = serializers.SerializerMethodField()
  30. acl = serializers.SerializerMethodField()
  31. api_url = serializers.SerializerMethodField()
  32. class Meta:
  33. model = Category
  34. fields = (
  35. 'id',
  36. 'parent',
  37. 'name',
  38. 'description',
  39. 'is_closed',
  40. 'threads',
  41. 'posts',
  42. 'last_post_on',
  43. 'last_thread_title',
  44. 'last_poster_name',
  45. 'css_class',
  46. 'is_read',
  47. 'subcategories',
  48. 'absolute_url',
  49. 'last_thread_url',
  50. 'last_post_url',
  51. 'last_poster_url',
  52. 'acl',
  53. 'api_url',
  54. 'level',
  55. 'lft',
  56. 'rght',
  57. )
  58. def get_description(self, obj):
  59. if obj.description:
  60. return {
  61. 'plain': obj.description,
  62. 'html': format_plaintext_for_html(obj.description),
  63. }
  64. else:
  65. return None
  66. def get_is_read(self, obj):
  67. try:
  68. return obj.is_read
  69. except AttributeError:
  70. return None
  71. def get_subcategories(self, obj):
  72. try:
  73. return CategorySerializer(obj.subcategories, many=True).data
  74. except AttributeError:
  75. return []
  76. def get_absolute_url(self, obj):
  77. return obj.get_absolute_url()
  78. @last_activity_detail
  79. def get_last_thread_url(self, obj):
  80. return obj.get_last_thread_url()
  81. @last_activity_detail
  82. def get_last_post_url(self, obj):
  83. return obj.get_last_post_url()
  84. @last_activity_detail
  85. def get_last_poster_url(self, obj):
  86. if obj.last_poster_id:
  87. return reverse('misago:user', kwargs={
  88. 'slug': obj.last_poster_slug,
  89. 'pk': obj.last_poster_id,
  90. })
  91. else:
  92. return None
  93. def get_acl(self, obj):
  94. try:
  95. return obj.acl
  96. except AttributeError:
  97. return {}
  98. def get_api_url(self, obj):
  99. return {
  100. 'read': obj.get_read_api_url(),
  101. }