"""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( 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)