Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

221 linhas
6.3 KiB

  1. from django.conf import settings
  2. from rest_framework import serializers
  3. from rest_framework.exceptions import ValidationError
  4. from taggit.models import Tag
  5. from core.models import Image, Board
  6. from core.models import Pin
  7. from django_images.models import Thumbnail
  8. from users.serializers import UserSerializer
  9. class ThumbnailSerializer(serializers.HyperlinkedModelSerializer):
  10. class Meta:
  11. model = Thumbnail
  12. fields = (
  13. "image",
  14. "width",
  15. "height",
  16. )
  17. class ImageSerializer(serializers.ModelSerializer):
  18. class Meta:
  19. model = Image
  20. fields = (
  21. "id",
  22. "image",
  23. "width",
  24. "height",
  25. "standard",
  26. "thumbnail",
  27. "square",
  28. )
  29. extra_kwargs = {
  30. "width": {"read_only": True},
  31. "height": {"read_only": True},
  32. }
  33. standard = ThumbnailSerializer(read_only=True)
  34. thumbnail = ThumbnailSerializer(read_only=True)
  35. square = ThumbnailSerializer(read_only=True)
  36. def create(self, validated_data):
  37. image = super(ImageSerializer, self).create(validated_data)
  38. Thumbnail.objects.get_or_create_at_sizes(image, settings.IMAGE_SIZES.keys())
  39. return image
  40. class TagSerializer(serializers.SlugRelatedField):
  41. class Meta:
  42. model = Tag
  43. fields = ("name",)
  44. queryset = Tag.objects.all()
  45. def __init__(self, **kwargs):
  46. super(TagSerializer, self).__init__(
  47. slug_field="name",
  48. **kwargs
  49. )
  50. def to_internal_value(self, data):
  51. obj, _ = self.get_queryset().get_or_create(
  52. defaults={self.slug_field: data, "slug": data},
  53. **{self.slug_field: data}
  54. )
  55. return obj
  56. class PinSerializer(serializers.HyperlinkedModelSerializer):
  57. class Meta:
  58. model = Pin
  59. fields = (
  60. settings.DRF_URL_FIELD_NAME,
  61. "id",
  62. "submitter",
  63. "url",
  64. "origin",
  65. "description",
  66. "referer",
  67. "image",
  68. "image_by_id",
  69. "tags",
  70. )
  71. submitter = UserSerializer(read_only=True)
  72. tags = TagSerializer(
  73. many=True,
  74. source="tag_list",
  75. required=False,
  76. )
  77. image = ImageSerializer(required=False, read_only=True)
  78. image_by_id = serializers.PrimaryKeyRelatedField(
  79. queryset=Image.objects.all(),
  80. write_only=True,
  81. required=False,
  82. )
  83. def create(self, validated_data):
  84. if 'url' not in validated_data and\
  85. 'image_by_id' not in validated_data:
  86. raise ValidationError(
  87. detail={
  88. "url-or-image": "Either url or image_by_id is required."
  89. },
  90. )
  91. submitter = self.context['request'].user
  92. if 'url' in validated_data and validated_data['url']:
  93. url = validated_data['url']
  94. image = Image.objects.create_for_url(
  95. url,
  96. validated_data.get('referer', url),
  97. )
  98. else:
  99. image = validated_data.pop("image_by_id")
  100. tags = validated_data.pop('tag_list', [])
  101. pin = Pin.objects.create(submitter=submitter, image=image, **validated_data)
  102. if tags:
  103. pin.tags.set(*tags)
  104. return pin
  105. def update(self, instance, validated_data):
  106. tags = validated_data.pop('tag_list', None)
  107. if tags:
  108. instance.tags.set(*tags)
  109. # change for image-id or image is not allowed
  110. validated_data.pop('image_by_id', None)
  111. return super(PinSerializer, self).update(instance, validated_data)
  112. class PinIdListField(serializers.ListField):
  113. child = serializers.IntegerField(
  114. min_value=1
  115. )
  116. class BoardAutoCompleteSerializer(serializers.HyperlinkedModelSerializer):
  117. class Meta:
  118. model = Board
  119. fields = (
  120. settings.DRF_URL_FIELD_NAME,
  121. 'id',
  122. 'name',
  123. )
  124. class BoardSerializer(serializers.HyperlinkedModelSerializer):
  125. class Meta:
  126. model = Board
  127. fields = (
  128. settings.DRF_URL_FIELD_NAME,
  129. "id",
  130. "name",
  131. "pins",
  132. "pins_detail",
  133. "published",
  134. "submitter",
  135. "pins_to_add",
  136. "pins_to_remove",
  137. )
  138. read_only_fields = ('submitter', 'published')
  139. extra_kwargs = {
  140. 'submitter': {"view_name": "users:user-detail"},
  141. }
  142. pins_detail = PinSerializer(source="pins", many=True, read_only=True)
  143. pins = serializers.HyperlinkedRelatedField(
  144. write_only=True,
  145. queryset=Pin.objects.all(),
  146. view_name="pin-detail",
  147. many=True,
  148. required=False,
  149. )
  150. pins_to_add = PinIdListField(
  151. max_length=10,
  152. write_only=True,
  153. required=False,
  154. allow_empty=False,
  155. help_text="only patch method works for this field",
  156. )
  157. pins_to_remove = PinIdListField(
  158. max_length=10,
  159. write_only=True,
  160. required=False,
  161. allow_empty=False,
  162. help_text="only patch method works for this field"
  163. )
  164. @staticmethod
  165. def _get_list(pins_id):
  166. return tuple(Pin.objects.filter(id__in=pins_id))
  167. def update(self, instance: Board, validated_data):
  168. pins_to_add = validated_data.pop("pins_to_add", [])
  169. pins_to_remove = validated_data.pop("pins_to_remove", [])
  170. instance = super(BoardSerializer, self).update(instance, validated_data)
  171. changed = False
  172. if pins_to_add:
  173. changed = True
  174. for pin in self._get_list(pins_to_add):
  175. instance.pins.add(pin)
  176. if pins_to_remove:
  177. changed = True
  178. for pin in self._get_list(pins_to_remove):
  179. instance.pins.remove(pin)
  180. if changed:
  181. instance.save()
  182. return instance
  183. def create(self, validated_data):
  184. validated_data.pop('pins_to_remove', None)
  185. validated_data.pop('pins_to_remove', None)
  186. user = self.context['request'].user
  187. if Board.objects.filter(name=validated_data['name'], submitter=user).exists():
  188. raise ValidationError(
  189. detail={"name": "board with this name already exists."}
  190. )
  191. validated_data['submitter'] = user
  192. return super(BoardSerializer, self).create(validated_data)