diff --git a/apps/advertisement/admin.py b/apps/advertisement/admin.py index 3754dca9..2728f4f9 100644 --- a/apps/advertisement/admin.py +++ b/apps/advertisement/admin.py @@ -14,3 +14,8 @@ class PageInline(admin.TabularInline): class AdvertisementModelAdmin(admin.ModelAdmin): """Admin model for model Advertisement""" inlines = (PageInline, ) + list_display = ('id', '__str__', 'block_level', + 'start', 'end', 'page_type') + list_filter = ('url', 'block_level', 'start', 'end', 'page_type', + 'pages__source') + date_hierarchy = 'created' diff --git a/apps/advertisement/models.py b/apps/advertisement/models.py index 66cd0024..b86a6168 100644 --- a/apps/advertisement/models.py +++ b/apps/advertisement/models.py @@ -71,11 +71,11 @@ class Advertisement(ProjectBaseMixin): return super().delete(using, keep_parents) @property - def mobile_page(self): + def mobile_pages(self): """Return mobile page""" - return self.pages.by_platform(Page.MOBILE).first() + return self.pages.by_platform(Page.MOBILE) @property - def web_page(self): + def web_pages(self): """Return web page""" - return self.pages.by_platform(Page.WEB).first() + return self.pages.by_platform(Page.WEB) diff --git a/apps/advertisement/serializers/back.py b/apps/advertisement/serializers/back.py index 9dc8b029..2ca5a18f 100644 --- a/apps/advertisement/serializers/back.py +++ b/apps/advertisement/serializers/back.py @@ -1,26 +1,14 @@ """Serializers for back office app advertisements""" -from main.serializers import PageBaseSerializer +from advertisement.serializers import AdvertisementBaseSerializer +from main.serializers import PageExtendedSerializer -class AdvertisementPageBaseSerializer(PageBaseSerializer): - """Base serializer for linking page w/ advertisement.""" +class AdvertisementDetailSerializer(AdvertisementBaseSerializer): + """Advertisement serializer for back office.""" + pages = PageExtendedSerializer(many=True, read_only=True) - class Meta(PageBaseSerializer.Meta): + class Meta(AdvertisementBaseSerializer.Meta): """Meta class.""" - - PageBaseSerializer.Meta.extra_kwargs.update({ - 'advertisement': {'write_only': True}, - 'image_url': {'required': True}, - 'width': {'required': True}, - 'height': {'required': True}, - }) - - -class AdvertisementPageListCreateSerializer(AdvertisementPageBaseSerializer): - """Serializer for linking page w/ advertisement.""" - - def create(self, validated_data): - """Overridden create method.""" - - validated_data['advertisement'] = self.context.get('view').get_object() - return super().create(validated_data) + fields = AdvertisementBaseSerializer.Meta.fields + [ + 'pages', + ] diff --git a/apps/advertisement/serializers/common.py b/apps/advertisement/serializers/common.py index 9caee0c2..b673475e 100644 --- a/apps/advertisement/serializers/common.py +++ b/apps/advertisement/serializers/common.py @@ -2,15 +2,15 @@ from rest_framework import serializers from advertisement import models -from translation.serializers import LanguageSerializer -from main.serializers import SiteShortSerializer, PageBaseSerializer -from translation.models import Language from main.models import SiteSettings +from main.serializers import PageTypeBaseSerializer +from translation.models import Language class AdvertisementBaseSerializer(serializers.ModelSerializer): """Base serializer for model Advertisement.""" - + page_type_detail = PageTypeBaseSerializer(read_only=True, + source='page_type') target_languages = serializers.PrimaryKeyRelatedField( queryset=Language.objects.all(), many=True, @@ -34,16 +34,17 @@ class AdvertisementBaseSerializer(serializers.ModelSerializer): 'target_sites', 'start', 'end', + 'page_type', + 'page_type_detail', ] + extra_kwargs = { + 'page_type': {'required': True, 'write_only': True} + } -class AdvertisementPageTypeCommonListSerializer(AdvertisementBaseSerializer): - """Serializer for AdvertisementPageTypeCommonView.""" - - page = PageBaseSerializer(source='common_page', read_only=True) - +class AdvertisementSerializer(AdvertisementBaseSerializer): + """Serializer for model Advertisement.""" class Meta(AdvertisementBaseSerializer.Meta): """Meta class.""" - fields = AdvertisementBaseSerializer.Meta.fields + [ - 'page', - ] + fields = AdvertisementBaseSerializer.Meta.fields.copy() + fields.pop(fields.index('page_type_detail')) diff --git a/apps/advertisement/serializers/mobile.py b/apps/advertisement/serializers/mobile.py index 80a19b82..37d810b4 100644 --- a/apps/advertisement/serializers/mobile.py +++ b/apps/advertisement/serializers/mobile.py @@ -1,15 +1,15 @@ """Serializers for mobile app advertisements""" -from advertisement.serializers import AdvertisementBaseSerializer +from advertisement.serializers import AdvertisementSerializer from main.serializers import PageBaseSerializer -class AdvertisementPageTypeMobileListSerializer(AdvertisementBaseSerializer): +class AdvertisementPageTypeMobileListSerializer(AdvertisementSerializer): """Serializer for AdvertisementPageTypeMobileView.""" - page = PageBaseSerializer(source='mobile_page', read_only=True) + pages = PageBaseSerializer(many=True, source='mobile_pages', read_only=True) - class Meta(AdvertisementBaseSerializer.Meta): + class Meta(AdvertisementSerializer.Meta): """Meta class.""" - fields = AdvertisementBaseSerializer.Meta.fields + [ - 'page', + fields = AdvertisementSerializer.Meta.fields + [ + 'pages', ] diff --git a/apps/advertisement/serializers/web.py b/apps/advertisement/serializers/web.py index 175f1875..a78c1f53 100644 --- a/apps/advertisement/serializers/web.py +++ b/apps/advertisement/serializers/web.py @@ -1,15 +1,15 @@ """Serializers for web app advertisements""" -from advertisement.serializers import AdvertisementBaseSerializer +from advertisement.serializers import AdvertisementSerializer from main.serializers import PageBaseSerializer -class AdvertisementPageTypeWebListSerializer(AdvertisementBaseSerializer): +class AdvertisementPageTypeWebListSerializer(AdvertisementSerializer): """Serializer for AdvertisementPageTypeWebView.""" - page = PageBaseSerializer(source='web_page', read_only=True) + pages = PageBaseSerializer(many=True, source='web_pages', read_only=True) - class Meta(AdvertisementBaseSerializer.Meta): + class Meta(AdvertisementSerializer.Meta): """Meta class.""" - fields = AdvertisementBaseSerializer.Meta.fields + [ - 'page', + fields = AdvertisementSerializer.Meta.fields + [ + 'pages', ] diff --git a/apps/advertisement/urls/back.py b/apps/advertisement/urls/back.py index 2502da0d..7a5cb133 100644 --- a/apps/advertisement/urls/back.py +++ b/apps/advertisement/urls/back.py @@ -9,10 +9,10 @@ app_name = 'advertisements' urlpatterns = [ path('', views.AdvertisementListCreateView.as_view(), name='list-create'), path('/', views.AdvertisementRUDView.as_view(), name='rud'), - path('/pages/', views.AdvertisementPageListCreateView.as_view(), - name='page-list-create'), - path('/pages//', views.AdvertisementPageRUDView.as_view(), - name='page-rud') + path('/pages/', views.AdvertisementPageCreateView.as_view(), + name='ad-page-create'), + path('/pages//', views.AdvertisementPageUDView.as_view(), + name='ad-page-update-destroy') ] urlpatterns += common_urlpatterns diff --git a/apps/advertisement/views/back.py b/apps/advertisement/views/back.py index a2973589..27a016a2 100644 --- a/apps/advertisement/views/back.py +++ b/apps/advertisement/views/back.py @@ -1,19 +1,19 @@ """Back office views for app advertisement""" -from rest_framework import generics +from rest_framework import generics, status +from rest_framework.response import Response from rest_framework import permissions from django.shortcuts import get_object_or_404 +from main.serializers import PageExtendedSerializer from advertisement.models import Advertisement -from rest_framework.response import Response -from rest_framework import status from advertisement.serializers import (AdvertisementBaseSerializer, - AdvertisementPageBaseSerializer, - AdvertisementPageListCreateSerializer) + AdvertisementDetailSerializer) class AdvertisementBackOfficeViewMixin(generics.GenericAPIView): """Base back office advertisement view.""" + pagination_class = None permission_classes = (permissions.IsAuthenticated, ) def get_queryset(self): @@ -31,14 +31,14 @@ class AdvertisementRUDView(AdvertisementBackOfficeViewMixin, generics.RetrieveUpdateDestroyAPIView): """Retrieve|Update|Destroy advertisement page view.""" - serializer_class = AdvertisementBaseSerializer + serializer_class = AdvertisementDetailSerializer -class AdvertisementPageListCreateView(AdvertisementBackOfficeViewMixin, - generics.ListCreateAPIView): - """Retrieve|Update|Destroy advertisement page view.""" +class AdvertisementPageCreateView(AdvertisementBackOfficeViewMixin, + generics.CreateAPIView): + """Create advertisement page view.""" - serializer_class = AdvertisementPageListCreateSerializer + serializer_class = PageExtendedSerializer def get_object(self): """Returns the object the view is displaying.""" @@ -56,12 +56,19 @@ class AdvertisementPageListCreateView(AdvertisementBackOfficeViewMixin, """Overridden get_queryset method.""" return self.get_object().pages.all() + def create(self, request, *args, **kwargs): + """Overridden create method.""" + request.data.update({'advertisement': self.get_object().pk}) + super().create(request, *args, **kwargs) + return Response(status=status.HTTP_200_OK) -class AdvertisementPageRUDView(AdvertisementBackOfficeViewMixin, - generics.RetrieveUpdateDestroyAPIView): - """Create|Retrieve|Update|Destroy advertisement page view.""" - serializer_class = AdvertisementPageBaseSerializer +class AdvertisementPageUDView(AdvertisementBackOfficeViewMixin, + generics.UpdateAPIView, + generics.DestroyAPIView): + """Update|Destroy advertisement page view.""" + + serializer_class = PageExtendedSerializer def get_object(self): """Returns the object the view is displaying.""" diff --git a/apps/advertisement/views/common.py b/apps/advertisement/views/common.py index 02c61873..12702d4b 100644 --- a/apps/advertisement/views/common.py +++ b/apps/advertisement/views/common.py @@ -3,8 +3,7 @@ from rest_framework import generics from rest_framework import permissions from advertisement.models import Advertisement -from advertisement.serializers import AdvertisementBaseSerializer, \ - AdvertisementPageTypeCommonListSerializer +from advertisement.serializers import AdvertisementBaseSerializer class AdvertisementBaseView(generics.GenericAPIView): @@ -16,8 +15,7 @@ class AdvertisementBaseView(generics.GenericAPIView): def get_queryset(self): """Overridden get queryset method.""" - return Advertisement.objects.with_base_related() \ - .by_locale(self.request.locale) + return Advertisement.objects.with_base_related() class AdvertisementPageTypeListView(AdvertisementBaseView, generics.ListAPIView): diff --git a/apps/main/admin.py b/apps/main/admin.py index 4b7038e7..315d1c2b 100644 --- a/apps/main/admin.py +++ b/apps/main/admin.py @@ -51,3 +51,6 @@ class PageTypeAdmin(admin.ModelAdmin): @admin.register(models.Page) class PageAdmin(admin.ModelAdmin): """Page admin.""" + list_display = ('id', '__str__', 'advertisement') + list_filter = ('advertisement__url', 'source') + date_hierarchy = 'created' diff --git a/apps/main/migrations/0041_auto_20191211_0631.py b/apps/main/migrations/0041_auto_20191211_0631.py new file mode 100644 index 00000000..973f4afd --- /dev/null +++ b/apps/main/migrations/0041_auto_20191211_0631.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.7 on 2019-12-11 06:31 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('advertisement', '0008_auto_20191116_1135'), + ('main', '0040_footer'), + ] + + operations = [ + migrations.AlterUniqueTogether( + name='page', + unique_together={('advertisement', 'source')}, + ), + ] diff --git a/apps/main/models.py b/apps/main/models.py index 0869169e..ae4168ea 100644 --- a/apps/main/models.py +++ b/apps/main/models.py @@ -305,7 +305,7 @@ class PageQuerySet(models.QuerySet): def by_platform(self, platform: int): """Filter by platform.""" - return self.filter(source=platform) + return self.filter(source__in=[Page.ALL, platform]) class Page(URLImageMixin, PlatformMixin, ProjectBaseMixin): @@ -325,6 +325,7 @@ class Page(URLImageMixin, PlatformMixin, ProjectBaseMixin): """Meta class.""" verbose_name = _('page') verbose_name_plural = _('pages') + unique_together = ('advertisement', 'source') def __str__(self): """Overridden dunder method.""" diff --git a/apps/main/serializers.py b/apps/main/serializers.py index 033da976..d586d71a 100644 --- a/apps/main/serializers.py +++ b/apps/main/serializers.py @@ -152,8 +152,6 @@ class SiteShortSerializer(serializers.ModelSerializer): ] - - class AwardBaseSerializer(serializers.ModelSerializer): """Award base serializer.""" @@ -234,10 +232,26 @@ class PageBaseSerializer(serializers.ModelSerializer): 'advertisement', ] extra_kwargs = { - 'establishment': {'write_only': True} + 'advertisement': {'write_only': True}, + 'image_url': {'required': True}, + 'width': {'required': True}, + 'height': {'required': True}, } +class PageExtendedSerializer(PageBaseSerializer): + """Extended serializer for model Page.""" + source_display = serializers.CharField(read_only=True, + source='get_source_display') + + class Meta(PageBaseSerializer.Meta): + """Meta class.""" + fields = PageBaseSerializer.Meta.fields + [ + 'source', + 'source_display', + ] + + class PageTypeBaseSerializer(serializers.ModelSerializer): """Serializer fro model PageType.""" diff --git a/apps/main/urls/back.py b/apps/main/urls/back.py index a9e55311..b4e196a3 100644 --- a/apps/main/urls/back.py +++ b/apps/main/urls/back.py @@ -20,6 +20,8 @@ urlpatterns = [ name='site-feature-rud'), path('footer/', views.FooterBackView.as_view(), name='footer-list-create'), path('footer//', views.FooterRUDBackView.as_view(), name='footer-rud'), + path('page-types/', views.PageTypeListCreateView.as_view(), + name='page-types-list-create') ] diff --git a/apps/main/views/back.py b/apps/main/views/back.py index 3d73f88c..f6f987af 100644 --- a/apps/main/views/back.py +++ b/apps/main/views/back.py @@ -4,7 +4,7 @@ from rest_framework import generics, permissions from main import serializers from main.filters import AwardFilter -from main.models import Award, Footer +from main.models import Award, Footer, PageType from main.views import SiteSettingsView, SiteListView @@ -81,3 +81,11 @@ class FooterRUDBackView(generics.RetrieveUpdateDestroyAPIView): permission_classes = (permissions.IsAuthenticatedOrReadOnly,) serializer_class = serializers.FooterBackSerializer queryset = Footer.objects.all() + + +class PageTypeListCreateView(generics.ListCreateAPIView): + """PageType back office view.""" + permission_classes = (permissions.IsAuthenticatedOrReadOnly, ) + pagination_class = None + serializer_class = serializers.PageTypeBaseSerializer + queryset = PageType.objects.all()