gm-148: modified news gallery

This commit is contained in:
Anatoly 2019-10-02 14:10:23 +03:00
parent 3234a71cde
commit 402bd32eda
7 changed files with 107 additions and 24 deletions

View File

@ -3,12 +3,18 @@ from django.utils.translation import gettext_lazy as _
from sorl.thumbnail.fields import ImageField as SORLImageField
from utils.methods import image_path
from django.conf import settings
from . import tasks
from utils.models import ProjectBaseMixin, SORLImageMixin, PlatformMixin
class ImageQuerySet(models.QuerySet):
"""QuerySet for model Image."""
def originals(self):
"""Return QuerySet with original images."""
return self.filter(parent__isnull=True)
class Image(ProjectBaseMixin, SORLImageMixin, PlatformMixin):
"""Image model."""
@ -42,3 +48,14 @@ class Image(ProjectBaseMixin, SORLImageMixin, PlatformMixin):
def __str__(self):
"""String representation"""
return str(self.id)
def delete_from_remote_storage(self, delete_original: bool = True):
"""Delete from remote storage"""
if settings.USE_CELERY:
tasks.delete_image_from_remote_storage.delay(self.id, delete_original)
else:
tasks.delete_image_from_remote_storage(self.id, delete_original)
@property
def childs(self):
return self.parent_image.filter(parent=self)

View File

@ -8,8 +8,6 @@ class ImageSerializer(serializers.ModelSerializer):
# REQUEST
file = serializers.ImageField(source='image',
write_only=True)
orientation = serializers.ChoiceField(choices=models.Image.ORIENTATIONS,
write_only=True)
# RESPONSE
url = serializers.ImageField(source='image',
@ -29,3 +27,6 @@ class ImageSerializer(serializers.ModelSerializer):
'orientation_display',
'title',
]
extra_kwargs = {
'orientation': {'write_only': True}
}

27
apps/gallery/tasks.py Normal file
View File

@ -0,0 +1,27 @@
"""Gallery app celery tasks."""
import logging
from celery import shared_task
from sorl.thumbnail import delete
from . import models
logging.basicConfig(format='[%(levelname)s] %(message)s', level=logging.INFO)
logger = logging.getLogger(__name__)
@shared_task
def delete_image_from_remote_storage(image_id, delete_original=True):
"""Delete an image from remote storage."""
image_qs = models.Image.objects.filter(id=image_id)
if image_qs.exists():
try:
image = image_qs.first()
# Delete from remote storage
delete(file_=image.image.file, delete_file=delete_original)
# Delete an instance of image
image.delete()
except:
logger.error(f'METHOD_NAME: delete_image_from_remote_storage\n'
f'DETAIL: Exception occurred while deleting an image '
f'from remote storage: image_id - {image_id}')

View File

@ -4,6 +4,7 @@ from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from rest_framework.reverse import reverse
from sorl.thumbnail import delete
from utils.models import BaseAttributes, TJSONField, TranslatedFieldsMixin
from random import sample as random_sample
@ -157,18 +158,14 @@ class News(BaseAttributes, TranslatedFieldsMixin):
def web_url(self):
return reverse('web:news:rud', kwargs={'slug': self.slug})
@property
def original_images(self):
return self.gallery.originals()
class NewsGalleryQuerySet(models.QuerySet):
"""QuerySet for model News"""
def originals(self):
"""Return QuerySet with original images."""
return self.filter(gallery__parent__isnull=True)
def crops(self):
"""Return QuerySet with cropped images."""
return self.filter(gallery__parent__isnull=False)
class NewsGallery(models.Model):

View File

@ -12,23 +12,51 @@ from news import models
from utils.serializers import TranslatedField, ProjectModelSerializer
class NewsImageSerializer(ImageSerializer):
"""News images"""
promo_web_url = serializers.SerializerMethodField()
promo_mobile_url = serializers.SerializerMethodField()
class NewsCropImageSerializer(ImageSerializer):
"""Serializer for returning crop images of news image."""
orientation_display = serializers.CharField(source='get_orientation_display',
read_only=True)
web_url = serializers.SerializerMethodField()
mobile_url = serializers.SerializerMethodField()
class Meta:
model = Image
fields = ImageSerializer.Meta.fields + [
'promo_web_url',
'promo_mobile_url'
fields = [
'id',
'title',
'orientation_display',
'web_url',
'mobile_url',
]
extra_kwargs = {
'orientation': {'write_only': True}
}
def get_promo_web_url(self, obj):
return obj.get_image_url(thumbnail_key='news_promo_horizontal_web')
def get_web_url(self, obj):
"""Return URL of cropped image by thumbnail."""
return obj.get_image_url('news_promo_horizontal_web')
def get_promo_mobile_url(self, obj):
return obj.get_image_url(thumbnail_key='news_promo_horizontal_mobile')
def get_mobile_url(self, obj):
"""Return URL of cropped image by thumbnail."""
return obj.get_image_url('news_promo_horizontal_mobile')
class NewsImageSerializer(ImageSerializer):
"""News images"""
url = serializers.URLField(source='image.url', read_only=True)
crops = NewsCropImageSerializer(source='childs', allow_null=True, many=True)
class Meta:
model = Image
fields = [
'id',
'title',
'url',
'crops',
]
extra_kwargs = {
'orientation': {'write_only': True}
}
class NewsTypeSerializer(serializers.ModelSerializer):
@ -51,7 +79,7 @@ class NewsBaseSerializer(ProjectModelSerializer):
# related fields
news_type = NewsTypeSerializer(read_only=True)
tags = MetaDataContentSerializer(read_only=True, many=True)
gallery = NewsImageSerializer(read_only=True, many=True)
gallery = NewsImageSerializer(source='original_images', read_only=True, many=True)
class Meta:
"""Meta class."""

View File

@ -4,6 +4,7 @@ from rest_framework import generics, permissions, status
from rest_framework.response import Response
from news import filters, models, serializers
from gallery.serializers import ImageSerializer
class NewsMixinView:
@ -90,10 +91,22 @@ class NewsBackOfficeGalleryCreateDestroyView(NewsBackOfficeMixinView,
super().create(request, *args, **kwargs)
return Response(status=status.HTTP_201_CREATED)
def destroy(self, request, *args, **kwargs):
"""Override destroy method."""
gallery_obj = self.get_object()
image_obj = gallery_obj.image
# Delete an instances of NewsGallery model
gallery_obj.delete()
# Delete an instance of Image model
image_obj.delete_from_remote_storage()
return Response(status=status.HTTP_204_NO_CONTENT)
class NewsBackOfficeGalleryListView(NewsBackOfficeMixinView, generics.ListAPIView):
"""Resource for returning gallery for news for back-office users."""
serializer_class = serializers.NewsImageSerializer
serializer_class = ImageSerializer
def get_object(self):
"""Override get_object method."""

View File

@ -8,7 +8,7 @@ ALLOWED_HOSTS = ['gm.id-east.ru', '95.213.204.126', '0.0.0.0']
SEND_SMS = False
SMS_CODE_SHOW = True
USE_CELERY = False
USE_CELERY = True
SCHEMA_URI = 'http'
DEFAULT_SUBDOMAIN = 'www'