"""News app views.""" from django.conf import settings from django.shortcuts import get_object_or_404 from rest_framework import generics, permissions from news import filters, models, serializers from rating.tasks import add_rating from utils.permissions import IsCountryAdmin, IsContentPageManager from utils.views import CreateDestroyGalleryViewMixin, FavoritesCreateDestroyMixinView, CarouselCreateDestroyMixinView from utils.serializers import ImageBaseSerializer class NewsMixinView: """News mixin.""" permission_classes = (permissions.AllowAny,) serializer_class = serializers.NewsBaseSerializer def get_queryset(self, *args, **kwargs): """Override get_queryset method.""" qs = models.News.objects.published() \ .with_base_related() \ .annotate_in_favorites(self.request.user) \ .order_by('-is_highlighted', '-start') country_code = self.request.country_code if country_code: if kwargs.get('international_preferred') and country_code in settings.INTERNATIONAL_COUNTRY_CODES: qs = qs.international_news() else: qs = qs.by_country_code(country_code) return qs def get_object(self): return self.get_queryset() \ .filter(slugs__values__contains=[self.kwargs['slug']]).first() class NewsListView(NewsMixinView, generics.ListAPIView): """News list view.""" serializer_class = serializers.NewsListSerializer filter_class = filters.NewsListFilterSet def get_queryset(self, *args, **kwargs): kwargs.update({'international_preferred': True}) return super().get_queryset(*args, **kwargs) class NewsDetailView(NewsMixinView, generics.RetrieveAPIView): """News detail view.""" lookup_field = None serializer_class = serializers.NewsDetailWebSerializer def get_queryset(self): """Override get_queryset method.""" qs = models.News.objects.all().annotate_in_favorites(self.request.user) return qs 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,) def get_queryset(self): """Override get_queryset method.""" qs = models.News.objects.with_base_related() \ .annotate_in_favorites(self.request.user) \ .order_by('-is_highlighted', '-created') return qs class NewsBackOfficeLCView(NewsBackOfficeMixinView, generics.ListCreateAPIView): """Resource for a list of news for back-office users.""" serializer_class = serializers.NewsBackOfficeBaseSerializer filter_class = filters.NewsListFilterSet 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, CreateDestroyGalleryViewMixin): """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.get('pk')) gallery = get_object_or_404(news.news_gallery, image_id=self.kwargs.get('image_id')) # May raise a permission denied self.check_object_permissions(self.request, gallery) return gallery class NewsBackOfficeGalleryListView(NewsBackOfficeMixinView, generics.ListAPIView): """Resource for returning gallery for news for back-office users.""" serializer_class = ImageBaseSerializer def get_object(self): """Override get_object method.""" qs = super(NewsBackOfficeGalleryListView, self).get_queryset() news = get_object_or_404(qs, pk=self.kwargs.get('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().crop_gallery 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) class NewsFavoritesCreateDestroyView(FavoritesCreateDestroyMixinView): """View for create/destroy news from favorites.""" _model = models.News serializer_class = serializers.NewsFavoritesCreateSerializer class NewsCarouselCreateDestroyView(CarouselCreateDestroyMixinView): """View for create/destroy news from carousel.""" _model = models.News serializer_class = serializers.NewsCarouselCreateSerializer