171 lines
6.2 KiB
Python
171 lines
6.2 KiB
Python
"""News app views."""
|
||
from django.conf import settings
|
||
from django.db.transaction import on_commit
|
||
from django.shortcuts import get_object_or_404
|
||
from rest_framework import generics, permissions, status
|
||
from rest_framework.response import Response
|
||
|
||
from gallery.tasks import delete_image
|
||
from news import filters, models, serializers
|
||
from rating.tasks import add_rating
|
||
from utils.permissions import IsCountryAdmin, IsContentPageManager
|
||
|
||
|
||
class NewsMixinView:
|
||
"""News mixin."""
|
||
|
||
permission_classes = (permissions.AllowAny,)
|
||
serializer_class = serializers.NewsBaseSerializer
|
||
|
||
def get_queryset(self, *args, **kwargs):
|
||
from django.conf import settings
|
||
"""Override get_queryset method."""
|
||
|
||
qs = models.News.objects.published() \
|
||
.with_base_related() \
|
||
.order_by('-is_highlighted', '-created')
|
||
country_code = self.request.country_code
|
||
if country_code:
|
||
|
||
# temp code
|
||
# Temporary stub for international news logic
|
||
# (по договорённости с заказчиком на демонстрации 4 ноября
|
||
# здесь будет 6 фиксированных новостей)
|
||
# TODO replace this stub with actual logic
|
||
if hasattr(settings, 'HARDCODED_INTERNATIONAL_NEWS_IDS'):
|
||
if country_code and country_code != 'www' and country_code != 'main':
|
||
qs = qs.by_country_code(country_code)
|
||
else:
|
||
qs = models.News.objects.filter(
|
||
old_id__in=settings.HARDCODED_INTERNATIONAL_NEWS_IDS)
|
||
return qs
|
||
# temp code
|
||
|
||
qs = qs.by_country_code(country_code)
|
||
return qs
|
||
|
||
|
||
class NewsListView(NewsMixinView, generics.ListAPIView):
|
||
"""News list view."""
|
||
|
||
serializer_class = serializers.NewsListSerializer
|
||
filter_class = filters.NewsListFilterSet
|
||
|
||
|
||
class NewsDetailView(NewsMixinView, generics.RetrieveAPIView):
|
||
"""News detail view."""
|
||
|
||
lookup_field = 'slug'
|
||
serializer_class = serializers.NewsDetailWebSerializer
|
||
|
||
def get_queryset(self):
|
||
"""Override get_queryset method."""
|
||
return super().get_queryset().with_extended_related()
|
||
|
||
|
||
class NewsTypeListView(generics.ListAPIView):
|
||
"""NewsType list view."""
|
||
|
||
pagination_class = None
|
||
permission_classes = (permissions.AllowAny, )
|
||
queryset = models.NewsType.objects.all()
|
||
serializer_class = serializers.NewsTypeSerializer
|
||
|
||
|
||
class NewsBackOfficeMixinView:
|
||
"""News back office mixin view."""
|
||
|
||
permission_classes = (permissions.IsAuthenticated,)
|
||
queryset = models.News.objects.with_base_related() \
|
||
.order_by('-is_highlighted', '-created')
|
||
|
||
|
||
class NewsBackOfficeLCView(NewsBackOfficeMixinView,
|
||
generics.ListCreateAPIView):
|
||
"""Resource for a list of news for back-office users."""
|
||
|
||
serializer_class = serializers.NewsBackOfficeBaseSerializer
|
||
create_serializers_class = serializers.NewsBackOfficeDetailSerializer
|
||
permission_classes = [IsCountryAdmin|IsContentPageManager]
|
||
|
||
def get_serializer_class(self):
|
||
"""Override serializer class."""
|
||
if self.request.method == 'POST':
|
||
return self.create_serializers_class
|
||
return super().get_serializer_class()
|
||
|
||
def get_queryset(self):
|
||
"""Override get_queryset method."""
|
||
return super().get_queryset().with_extended_related()
|
||
|
||
|
||
class NewsBackOfficeGalleryCreateDestroyView(NewsBackOfficeMixinView,
|
||
generics.CreateAPIView,
|
||
generics.DestroyAPIView):
|
||
"""Resource for a create gallery for news for back-office users."""
|
||
serializer_class = serializers.NewsBackOfficeGallerySerializer
|
||
|
||
def get_object(self):
|
||
"""
|
||
Returns the object the view is displaying.
|
||
"""
|
||
news_qs = self.filter_queryset(self.get_queryset())
|
||
|
||
news = get_object_or_404(news_qs, pk=self.kwargs['pk'])
|
||
gallery = get_object_or_404(news.news_gallery, image_id=self.kwargs['image_id'])
|
||
|
||
# May raise a permission denied
|
||
self.check_object_permissions(self.request, gallery)
|
||
|
||
return gallery
|
||
|
||
def create(self, request, *args, **kwargs):
|
||
"""Overridden create method"""
|
||
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()
|
||
if settings.USE_CELERY:
|
||
on_commit(lambda: delete_image.delay(image_id=gallery_obj.image.id,
|
||
completely=False))
|
||
else:
|
||
on_commit(lambda: delete_image(image_id=gallery_obj.image.id,
|
||
completely=False))
|
||
# Delete an instances of NewsGallery model
|
||
gallery_obj.delete()
|
||
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
|
||
|
||
def get_object(self):
|
||
"""Override get_object method."""
|
||
qs = super(NewsBackOfficeGalleryListView, self).get_queryset()
|
||
news = get_object_or_404(qs, pk=self.kwargs['pk'])
|
||
|
||
# May raise a permission denied
|
||
self.check_object_permissions(self.request, news)
|
||
|
||
return news
|
||
|
||
def get_queryset(self):
|
||
"""Override get_queryset method."""
|
||
return self.get_object().gallery.all()
|
||
|
||
|
||
class NewsBackOfficeRUDView(NewsBackOfficeMixinView,
|
||
generics.RetrieveUpdateDestroyAPIView):
|
||
"""Resource for detailed information about news for back-office users."""
|
||
|
||
serializer_class = serializers.NewsBackOfficeDetailSerializer
|
||
permission_classes = [IsCountryAdmin|IsContentPageManager]
|
||
|
||
def get(self, request, pk, *args, **kwargs):
|
||
add_rating(remote_addr=request.META.get('REMOTE_ADDR'),
|
||
pk=pk, model='news', app_label='news')
|
||
return self.retrieve(request, *args, **kwargs)
|