25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

serializers.py 3.8 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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
  6. from core.models import Pin
  7. from django_images.models import Thumbnail
  8. from users.models import User
  9. class UserSerializer(serializers.HyperlinkedModelSerializer):
  10. class Meta:
  11. model = User
  12. fields = (
  13. 'username',
  14. 'gravatar',
  15. settings.DRF_URL_FIELD_NAME,
  16. )
  17. class ThumbnailSerializer(serializers.HyperlinkedModelSerializer):
  18. class Meta:
  19. model = Thumbnail
  20. fields = (
  21. "image",
  22. "width",
  23. "height",
  24. )
  25. class ImageSerializer(serializers.ModelSerializer):
  26. class Meta:
  27. model = Image
  28. fields = (
  29. "id",
  30. "image",
  31. "width",
  32. "height",
  33. "standard",
  34. "thumbnail",
  35. "square",
  36. )
  37. extra_kwargs = {
  38. "width": {"read_only": True},
  39. "height": {"read_only": True},
  40. }
  41. standard = ThumbnailSerializer(read_only=True)
  42. thumbnail = ThumbnailSerializer(read_only=True)
  43. square = ThumbnailSerializer(read_only=True)
  44. def create(self, validated_data):
  45. image = super(ImageSerializer, self).create(validated_data)
  46. for size in settings.IMAGE_SIZES:
  47. Thumbnail.objects.get_or_create_at_size(image.pk, size)
  48. return image
  49. class TagSerializer(serializers.SlugRelatedField):
  50. class Meta:
  51. model = Tag
  52. fields = ("name",)
  53. queryset = Tag.objects.all()
  54. def __init__(self, **kwargs):
  55. super(TagSerializer, self).__init__(
  56. slug_field="name",
  57. **kwargs
  58. )
  59. def to_internal_value(self, data):
  60. obj, _ = self.get_queryset().get_or_create(
  61. **{self.slug_field: data},
  62. defaults={self.slug_field: data, "slug": data}
  63. )
  64. return obj
  65. class PinSerializer(serializers.HyperlinkedModelSerializer):
  66. class Meta:
  67. model = Pin
  68. fields = (
  69. settings.DRF_URL_FIELD_NAME,
  70. "id",
  71. "submitter",
  72. "url",
  73. "origin",
  74. "description",
  75. "referer",
  76. "image",
  77. "image_by_id",
  78. "tags",
  79. )
  80. submitter = UserSerializer(read_only=True)
  81. tags = TagSerializer(
  82. many=True,
  83. source="tag_list",
  84. required=False,
  85. )
  86. image = ImageSerializer(required=False, read_only=True)
  87. image_by_id = serializers.PrimaryKeyRelatedField(
  88. queryset=Image.objects.all(),
  89. write_only=True,
  90. required=False,
  91. )
  92. def create(self, validated_data):
  93. if 'url' not in validated_data and\
  94. 'image_by_id' not in validated_data:
  95. raise ValidationError(
  96. detail={
  97. "url-or-image": "Either url or image_by_id is required."
  98. },
  99. )
  100. submitter = self.context['request'].user
  101. if 'url' in validated_data and validated_data['url']:
  102. url = validated_data['url']
  103. image = Image.objects.create_for_url(
  104. url,
  105. validated_data.get('referer', url),
  106. )
  107. else:
  108. image = validated_data.pop("image_by_id")
  109. tags = validated_data.pop('tag_list', [])
  110. pin = Pin.objects.create(submitter=submitter, image=image, **validated_data)
  111. if tags:
  112. pin.tags.set(*tags)
  113. return pin
  114. def update(self, instance, validated_data):
  115. tags = validated_data.pop('tag_list', None)
  116. if tags:
  117. instance.tags.set(*tags)
  118. # change for image-id or image is not allowed
  119. validated_data.pop('image_by_id', None)
  120. return super(PinSerializer, self).update(instance, validated_data)