Merge branch 'develop' of ssh://gl.id-east.ru:222/gm/gm-backend into develop

This commit is contained in:
Dmitriy Kuzmenko 2019-11-15 16:05:01 +03:00
commit 8f6cf792e7
31 changed files with 541 additions and 111 deletions

View File

@ -2,8 +2,15 @@
from django.contrib import admin from django.contrib import admin
from advertisement import models from advertisement import models
from main.models import Page
class PageInline(admin.TabularInline):
model = Page
extra = 0
@admin.register(models.Advertisement) @admin.register(models.Advertisement)
class AdvertisementModelAdmin(admin.ModelAdmin): class AdvertisementModelAdmin(admin.ModelAdmin):
"""Admin model for model Advertisement""" """Admin model for model Advertisement"""
inlines = (PageInline, )

View File

@ -0,0 +1,34 @@
# Generated by Django 2.2.7 on 2019-11-15 07:50
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('advertisement', '0005_auto_20191108_0923'),
]
operations = [
migrations.RemoveField(
model_name='advertisement',
name='height',
),
migrations.RemoveField(
model_name='advertisement',
name='image_url',
),
migrations.RemoveField(
model_name='advertisement',
name='source',
),
migrations.RemoveField(
model_name='advertisement',
name='width',
),
migrations.AddField(
model_name='advertisement',
name='end',
field=models.DateTimeField(blank=True, default=None, null=True, verbose_name='end'),
),
]

View File

@ -0,0 +1,30 @@
# Generated by Django 2.2.7 on 2019-11-15 07:50
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('advertisement', '0006_auto_20191115_0750'),
('main', '0036_auto_20191115_0750'),
]
operations = [
migrations.AddField(
model_name='advertisement',
name='page_type',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='advertisements', to='main.PageType', verbose_name='page type'),
),
migrations.AddField(
model_name='advertisement',
name='sites',
field=models.ManyToManyField(related_name='advertisements', to='main.SiteSettings', verbose_name='site'),
),
migrations.AddField(
model_name='advertisement',
name='start',
field=models.DateTimeField(null=True, verbose_name='start'),
),
]

View File

@ -6,18 +6,47 @@ from django.utils.translation import gettext_lazy as _
from translation.models import Language from translation.models import Language
from utils.models import ProjectBaseMixin, ImageMixin, PlatformMixin, URLImageMixin from utils.models import ProjectBaseMixin, ImageMixin, PlatformMixin, URLImageMixin
from main.models import Page
class Advertisement(URLImageMixin, ProjectBaseMixin, PlatformMixin): class AdvertisementQuerySet(models.QuerySet):
"""QuerySet for model Advertisement."""
def with_base_related(self):
"""Return QuerySet with base related"""
return self.select_related('page_type') \
.prefetch_related('target_languages', 'sites', 'pages')
def by_page_type(self, page_type: str):
"""Filter Advertisement by page type."""
return self.filter(page_type__name=page_type)
def by_locale(self, locale):
"""Filter by locale."""
return self.filter(target_languages__locale=locale)
class Advertisement(ProjectBaseMixin):
"""Advertisement model.""" """Advertisement model."""
old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None) old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None)
uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True) uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
url = models.URLField(verbose_name=_('Ad URL')) url = models.URLField(verbose_name=_('Ad URL'))
width = models.PositiveIntegerField(verbose_name=_('Block width')) # 300
height = models.PositiveIntegerField(verbose_name=_('Block height')) # 250
block_level = models.CharField(verbose_name=_('Block level'), max_length=10, blank=True, null=True) block_level = models.CharField(verbose_name=_('Block level'), max_length=10, blank=True, null=True)
target_languages = models.ManyToManyField(Language) target_languages = models.ManyToManyField(Language)
start = models.DateTimeField(null=True,
verbose_name=_('start'))
end = models.DateTimeField(blank=True, null=True, default=None,
verbose_name=_('end'))
sites = models.ManyToManyField('main.SiteSettings',
related_name='advertisements',
verbose_name=_('site'))
page_type = models.ForeignKey('main.PageType', on_delete=models.PROTECT,
null=True,
related_name='advertisements',
verbose_name=_('page type'))
objects = AdvertisementQuerySet.as_manager()
class Meta: class Meta:
verbose_name = _('Advertisement') verbose_name = _('Advertisement')
@ -25,3 +54,13 @@ class Advertisement(URLImageMixin, ProjectBaseMixin, PlatformMixin):
def __str__(self): def __str__(self):
return str(self.url) return str(self.url)
@property
def mobile_page(self):
"""Return mobile page"""
return self.pages.by_platform(Page.MOBILE).first()
@property
def web_page(self):
"""Return web page"""
return self.pages.by_platform(Page.WEB).first()

View File

@ -0,0 +1,3 @@
from .common import *
from .mobile import *
from .web import *

View File

@ -0,0 +1,39 @@
"""Serializers for app advertisements"""
from rest_framework import serializers
from advertisement import models
from translation.serializers import LanguageSerializer
from main.serializers import SiteShortSerializer
from main.serializers import PageBaseSerializer
class AdvertisementBaseSerializer(serializers.ModelSerializer):
"""Base serializer for model Advertisement."""
languages = LanguageSerializer(many=True, read_only=True)
sites = SiteShortSerializer(many=True, read_only=True)
class Meta:
model = models.Advertisement
fields = [
'id',
'uuid',
'url',
'block_level',
'languages',
'sites',
'start',
'end',
]
class AdvertisementPageTypeCommonListSerializer(AdvertisementBaseSerializer):
"""Serializer for AdvertisementPageTypeCommonView."""
page = PageBaseSerializer(source='common_page', read_only=True)
class Meta(AdvertisementBaseSerializer.Meta):
"""Meta class."""
fields = AdvertisementBaseSerializer.Meta.fields + [
'page',
]

View File

@ -0,0 +1,15 @@
"""Serializers for mobile app advertisements"""
from advertisement.serializers import AdvertisementBaseSerializer
from main.serializers import PageBaseSerializer
class AdvertisementPageTypeMobileListSerializer(AdvertisementBaseSerializer):
"""Serializer for AdvertisementPageTypeMobileView."""
page = PageBaseSerializer(source='mobile_page', read_only=True)
class Meta(AdvertisementBaseSerializer.Meta):
"""Meta class."""
fields = AdvertisementBaseSerializer.Meta.fields + [
'page',
]

View File

@ -1,22 +1,15 @@
"""Serializers for app advertisements""" """Serializers for web app advertisements"""
from rest_framework import serializers from advertisement.serializers import AdvertisementBaseSerializer
from main.serializers import PageBaseSerializer
from advertisement import models
from translation.serializers import LanguageSerializer
class AdvertisementSerializer(serializers.ModelSerializer): class AdvertisementPageTypeWebListSerializer(AdvertisementBaseSerializer):
"""Serializer for model Advertisement.""" """Serializer for AdvertisementPageTypeWebView."""
class Meta: page = PageBaseSerializer(source='web_page', read_only=True)
model = models.Advertisement
fields = ( class Meta(AdvertisementBaseSerializer.Meta):
'id', """Meta class."""
'uuid', fields = AdvertisementBaseSerializer.Meta.fields + [
'url', 'page',
'image_url', ]
'width',
'height',
'block_level',
'source'
)

View File

@ -0,0 +1,8 @@
"""Advertisement common urlpaths."""
from django.urls import path
app_name = 'advertisements'
common_urlpatterns = [
]

View File

@ -0,0 +1,14 @@
"""Advertisement common urlpaths."""
from django.urls import path
from advertisement.views import mobile as views
from .common import common_urlpatterns
app_name = 'advertisements'
urlpatterns = [
path('<page_type>/', views.AdvertisementPageTypeMobileListView.as_view(), name='list'),
]
urlpatterns += common_urlpatterns

View File

@ -2,9 +2,12 @@
from django.urls import path from django.urls import path
from advertisement.views import web as views from advertisement.views import web as views
from .common import common_urlpatterns
app_name = 'advertisements' app_name = 'advertisements'
urlpatterns = [ urlpatterns = [
path('<str:page>/', views.AdvertisementListView.as_view(), name='list') path('<page_type>/', views.AdvertisementPageTypeWebListView.as_view(), name='list'),
] ]
urlpatterns += common_urlpatterns

View File

@ -0,0 +1,3 @@
from .common import *
from .mobile import *
from .web import *

View File

@ -0,0 +1,32 @@
"""Views for app advertisement"""
from rest_framework import generics
from rest_framework import permissions
from advertisement.models import Advertisement
from advertisement.serializers import AdvertisementBaseSerializer, \
AdvertisementPageTypeCommonListSerializer
class AdvertisementBaseView(generics.GenericAPIView):
"""Advertisement list view."""
pagination_class = None
permission_classes = (permissions.AllowAny, )
serializer_class = AdvertisementBaseSerializer
def get_queryset(self):
"""Overridden get queryset method."""
return Advertisement.objects.with_base_related() \
.by_locale(self.request.locale)
class AdvertisementPageTypeListView(AdvertisementBaseView, generics.ListAPIView):
"""Advertisement list view by page type."""
def get_queryset(self):
"""Overridden get queryset method."""
product_type = self.kwargs.get('page_type')
qs = super(AdvertisementPageTypeListView, self).get_queryset()
if product_type:
return qs.by_page_type(product_type)
return qs.none()

View File

@ -0,0 +1,9 @@
"""Mobile views for app advertisement"""
from advertisement.serializers import AdvertisementPageTypeMobileListSerializer
from .common import AdvertisementPageTypeListView
class AdvertisementPageTypeMobileListView(AdvertisementPageTypeListView):
"""Advertisement mobile list view."""
serializer_class = AdvertisementPageTypeMobileListSerializer

View File

@ -1,19 +1,9 @@
"""Views for app advertisement""" """Web views for app advertisement"""
from rest_framework import generics from advertisement.serializers import AdvertisementPageTypeWebListSerializer
from rest_framework import permissions from .common import AdvertisementPageTypeListView
from advertisement import models
from advertisement.serializers import web as serializers
class AdvertisementListView(generics.ListAPIView): class AdvertisementPageTypeWebListView(AdvertisementPageTypeListView):
"""List view for model Advertisement""" """Advertisement mobile list view."""
pagination_class = None
model = models.Advertisement
permission_classes = (permissions.AllowAny,)
serializer_class = serializers.AdvertisementSerializer
def get_queryset(self): serializer_class = AdvertisementPageTypeWebListSerializer
return models.Advertisement.objects\
.filter(page__page_name__contains=self.kwargs['page'])\
.filter(target_languages__locale=self.request.locale)

View File

@ -35,3 +35,8 @@ class CurrencyContentAdmin(admin.ModelAdmin):
@admin.register(models.Carousel) @admin.register(models.Carousel)
class CarouselAdmin(admin.ModelAdmin): class CarouselAdmin(admin.ModelAdmin):
"""Carousel admin.""" """Carousel admin."""
@admin.register(models.PageType)
class PageTypeAdmin(admin.ModelAdmin):
"""PageType admin."""

View File

@ -0,0 +1,85 @@
# Generated by Django 2.2.7 on 2019-11-15 07:50
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('advertisement', '0006_auto_20191115_0750'),
('main', '0035_merge_20191112_1218'),
]
operations = [
migrations.CreateModel(
name='PageType',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(default=django.utils.timezone.now, editable=False, verbose_name='Date created')),
('modified', models.DateTimeField(auto_now=True, verbose_name='Date updated')),
('name', models.CharField(max_length=255, unique=True, verbose_name='name')),
],
options={
'verbose_name': 'page type',
'verbose_name_plural': 'page types',
},
),
migrations.AlterModelOptions(
name='page',
options={'verbose_name': 'page', 'verbose_name_plural': 'pages'},
),
migrations.RemoveField(
model_name='page',
name='advertisements',
),
migrations.RemoveField(
model_name='page',
name='page_name',
),
migrations.AddField(
model_name='page',
name='advertisement',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='pages', to='advertisement.Advertisement', verbose_name='advertisement'),
),
migrations.AddField(
model_name='page',
name='created',
field=models.DateTimeField(default=django.utils.timezone.now, editable=False, verbose_name='Date created'),
),
migrations.AddField(
model_name='page',
name='height',
field=models.PositiveIntegerField(null=True, verbose_name='Block height'),
),
migrations.AddField(
model_name='page',
name='image_url',
field=models.URLField(blank=True, default=None, null=True, verbose_name='Image URL path'),
),
migrations.AddField(
model_name='page',
name='modified',
field=models.DateTimeField(auto_now=True, verbose_name='Date updated'),
),
migrations.AddField(
model_name='page',
name='source',
field=models.PositiveSmallIntegerField(choices=[(0, 'Mobile'), (1, 'Web'), (2, 'All')], default=0, verbose_name='Source'),
),
migrations.AddField(
model_name='page',
name='width',
field=models.PositiveIntegerField(null=True, verbose_name='Block width'),
),
migrations.RemoveField(
model_name='feature',
name='route',
),
migrations.AddField(
model_name='feature',
name='route',
field=models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.PROTECT, to='main.PageType'),
),
]

View File

@ -10,7 +10,6 @@ from django.db import models
from django.db.models import Q from django.db.models import Q
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from advertisement.models import Advertisement
from configuration.models import TranslationSettings from configuration.models import TranslationSettings
from location.models import Country from location.models import Country
from main import methods from main import methods
@ -99,27 +98,12 @@ class SiteSettings(ProjectBaseMixin):
domain=settings.SITE_DOMAIN_URI) domain=settings.SITE_DOMAIN_URI)
class Page(models.Model):
"""Page model."""
page_name = models.CharField(max_length=255, unique=True)
advertisements = models.ManyToManyField(Advertisement)
class Meta:
"""Meta class."""
verbose_name = _('Page')
verbose_name_plural = _('Pages')
def __str__(self):
return f'{self.page_name}'
class Feature(ProjectBaseMixin, PlatformMixin): class Feature(ProjectBaseMixin, PlatformMixin):
"""Feature model.""" """Feature model."""
slug = models.SlugField(max_length=255, unique=True) slug = models.SlugField(max_length=255, unique=True)
priority = models.IntegerField(unique=True, null=True, default=None) priority = models.IntegerField(unique=True, null=True, default=None)
route = models.ForeignKey(Page, on_delete=models.PROTECT, null=True, default=None) route = models.ForeignKey('PageType', on_delete=models.PROTECT, null=True, default=None)
site_settings = models.ManyToManyField(SiteSettings, through='SiteFeature') site_settings = models.ManyToManyField(SiteSettings, through='SiteFeature')
class Meta: class Meta:
@ -310,3 +294,56 @@ class Carousel(models.Model):
elif self.link not in EMPTY_VALUES: elif self.link not in EMPTY_VALUES:
return 'external' return 'external'
return None return None
class PageQuerySet(models.QuerySet):
"""QuerySet for model Page."""
def by_platform(self, platform: int):
"""Filter by platform."""
return self.filter(source=platform)
class Page(URLImageMixin, PlatformMixin, ProjectBaseMixin):
"""Page model."""
advertisement = models.ForeignKey('advertisement.Advertisement',
on_delete=models.PROTECT, null=True,
related_name='pages',
verbose_name=_('advertisement'))
width = models.PositiveIntegerField(null=True,
verbose_name=_('Block width')) # 300
height = models.PositiveIntegerField(null=True,
verbose_name=_('Block height')) # 250
objects = PageQuerySet.as_manager()
class Meta:
"""Meta class."""
verbose_name = _('page')
verbose_name_plural = _('pages')
def __str__(self):
"""Overridden dunder method."""
return self.get_source_display()
class PageTypeQuerySet(models.QuerySet):
"""QuerySet for model PageType."""
class PageType(ProjectBaseMixin):
"""Page type model."""
name = models.CharField(max_length=255, unique=True,
verbose_name=_('name'))
objects = PageTypeQuerySet.as_manager()
class Meta:
"""Meta class."""
verbose_name = _('page type')
verbose_name_plural = _('page types')
def __str__(self):
"""Overridden dunder method."""
return self.name

View File

@ -1,7 +1,6 @@
"""Main app serializers.""" """Main app serializers."""
from rest_framework import serializers from rest_framework import serializers
from advertisement.serializers.web import AdvertisementSerializer
from location.serializers import CountrySerializer from location.serializers import CountrySerializer
from main import models from main import models
from utils.serializers import ProjectModelSerializer, TranslatedField, RecursiveFieldSerializer from utils.serializers import ProjectModelSerializer, TranslatedField, RecursiveFieldSerializer
@ -25,7 +24,7 @@ class SiteFeatureSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(source='feature.id') id = serializers.IntegerField(source='feature.id')
slug = serializers.CharField(source='feature.slug') slug = serializers.CharField(source='feature.slug')
priority = serializers.IntegerField(source='feature.priority') priority = serializers.IntegerField(source='feature.priority')
route = serializers.CharField(source='feature.route.page_name') route = serializers.CharField(source='feature.route.name')
source = serializers.IntegerField(source='feature.source') source = serializers.IntegerField(source='feature.source')
nested = RecursiveFieldSerializer(many=True, allow_null=True) nested = RecursiveFieldSerializer(many=True, allow_null=True)
@ -94,11 +93,20 @@ class SiteSerializer(serializers.ModelSerializer):
class Meta: class Meta:
"""Meta class.""" """Meta class."""
model = models.SiteSettings model = models.SiteSettings
fields = ('subdomain', 'site_url', 'country') fields = ('subdomain', 'site_url', 'country')
class SiteShortSerializer(serializers.ModelSerializer):
"""Short serializer for model SiteSettings."""
class Meta(SiteSerializer.Meta):
"""Meta class."""
fields = [
'subdomain',
]
# class SiteFeatureSerializer(serializers.ModelSerializer): # class SiteFeatureSerializer(serializers.ModelSerializer):
# """Site feature serializer.""" # """Site feature serializer."""
# #
@ -167,15 +175,27 @@ class CarouselListSerializer(serializers.ModelSerializer):
] ]
class PageSerializer(serializers.ModelSerializer): class PageBaseSerializer(serializers.ModelSerializer):
page_name = serializers.CharField() """Serializer for model Page"""
advertisements = AdvertisementSerializer(source='advertisements', many=True)
class Meta: class Meta:
"""Meta class.""" """Meta class."""
model = models.Carousel model = models.Page
fields = [ fields = [
'id', 'id',
'page_name', 'image_url',
'advertisements' 'width',
'height',
] ]
class PageTypeBaseSerializer(serializers.ModelSerializer):
"""Serializer fro model PageType."""
class Meta:
"""Meta class."""
model = models.PageType
fields = [
'id',
'name',
]

View File

@ -70,6 +70,9 @@ class CarouselListView(generics.ListAPIView):
def get_queryset(self): def get_queryset(self):
country_code = self.request.country_code country_code = self.request.country_code
if hasattr(settings, 'CAROUSEL_ITEMS') and country_code in ['www', 'main']:
qs = models.Carousel.objects.filter(id__in=settings.CAROUSEL_ITEMS)
return qs
qs = models.Carousel.objects.is_parsed().active() qs = models.Carousel.objects.is_parsed().active()
if country_code: if country_code:
qs = qs.by_country_code(country_code) qs = qs.by_country_code(country_code)

View File

@ -95,12 +95,14 @@ class NewsQuerySet(TranslationQuerysetMixin):
# todo: filter by best score # todo: filter by best score
# todo: filter by country? # todo: filter by country?
def should_read(self, news): def should_read(self, news, user):
return self.model.objects.exclude(pk=news.pk).published(). \ return self.model.objects.exclude(pk=news.pk).published(). \
annotate_in_favorites(user). \
with_base_related().by_type(news.news_type).distinct().order_by('?') with_base_related().by_type(news.news_type).distinct().order_by('?')
def same_theme(self, news): def same_theme(self, news, user):
return self.model.objects.exclude(pk=news.pk).published(). \ return self.model.objects.exclude(pk=news.pk).published(). \
annotate_in_favorites(user). \
with_base_related().by_type(news.news_type). \ with_base_related().by_type(news.news_type). \
by_tags(news.tags.all()).distinct().order_by('-start') by_tags(news.tags.all()).distinct().order_by('-start')
@ -212,13 +214,11 @@ class News(BaseAttributes, TranslatedFieldsMixin):
def web_url(self): def web_url(self):
return reverse('web:news:rud', kwargs={'slug': self.slug}) return reverse('web:news:rud', kwargs={'slug': self.slug})
@property def should_read(self, user):
def should_read(self): return self.__class__.objects.should_read(self, user)[:3]
return self.__class__.objects.should_read(self)[:3]
@property def same_theme(self, user):
def same_theme(self): return self.__class__.objects.same_theme(self, user)[:3]
return self.__class__.objects.same_theme(self)[:3]
@property @property
def main_image(self): def main_image(self):

View File

@ -1,6 +1,7 @@
"""News app common serializers.""" """News app common serializers."""
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from rest_framework import serializers from rest_framework import serializers
from rest_framework.fields import SerializerMethodField
from account.serializers.common import UserBaseSerializer from account.serializers.common import UserBaseSerializer
from gallery.models import Image from gallery.models import Image
@ -151,7 +152,7 @@ class NewsBaseSerializer(ProjectModelSerializer):
'tags', 'tags',
'slug', 'slug',
'in_favorites', 'in_favorites',
'view_counter' 'view_counter',
) )
@ -208,8 +209,8 @@ class NewsDetailSerializer(NewsBaseSerializer):
class NewsDetailWebSerializer(NewsDetailSerializer): class NewsDetailWebSerializer(NewsDetailSerializer):
"""News detail serializer for web users..""" """News detail serializer for web users.."""
same_theme = NewsSimilarListSerializer(many=True, read_only=True) same_theme = SerializerMethodField()
should_read = NewsSimilarListSerializer(many=True, read_only=True) should_read = SerializerMethodField()
agenda = AgendaSerializer() agenda = AgendaSerializer()
banner = NewsBannerSerializer() banner = NewsBannerSerializer()
@ -223,6 +224,12 @@ class NewsDetailWebSerializer(NewsDetailSerializer):
'banner', 'banner',
) )
def get_same_theme(self, obj):
return NewsSimilarListSerializer(obj.same_theme(self.context['request'].user), many=True, read_only=True).data
def get_should_read(self, obj):
return NewsSimilarListSerializer(obj.should_read(self.context['request'].user), many=True, read_only=True).data
class NewsBackOfficeBaseSerializer(NewsBaseSerializer): class NewsBackOfficeBaseSerializer(NewsBaseSerializer):
"""News back office base serializer.""" """News back office base serializer."""

View File

@ -1,5 +1,7 @@
from pprint import pprint from pprint import pprint
from django.db.models import Count
from transfer.models import EmailAddresses, NewsletterSubscriber from transfer.models import EmailAddresses, NewsletterSubscriber
from transfer.serializers.notification import SubscriberSerializer, NewsletterSubscriberSerializer from transfer.serializers.notification import SubscriberSerializer, NewsletterSubscriberSerializer
@ -25,12 +27,12 @@ def transfer_newsletter_subscriber():
'email_address__locale', 'email_address__locale',
'created_at', 'created_at',
) )
serialized_data = NewsletterSubscriberSerializer(data=list(queryset.values()), many=True) # serialized_data = NewsletterSubscriberSerializer(data=list(queryset.values()), many=True)
if serialized_data.is_valid(): # if serialized_data.is_valid():
serialized_data.save() # serialized_data.save()
else: # else:
pprint(f'NewsletterSubscriber serializer errors: {serialized_data.errors}') # pprint(f'NewsletterSubscriber serializer errors: {serialized_data.errors}')
data_types = { data_types = {

View File

@ -20,6 +20,19 @@ class TagsDocumentSerializer(serializers.Serializer):
return get_translated_value(obj.label) return get_translated_value(obj.label)
class EstablishmentTypeSerializer(serializers.Serializer):
"""Establishment type serializer for ES Document"""
id = serializers.IntegerField()
name_translated = serializers.SerializerMethodField()
index_name = serializers.CharField()
def get_name_translated(self, obj):
if isinstance(obj, dict):
return get_translated_value(obj.get('name'))
return get_translated_value(obj.name)
class ProductSubtypeDocumentSerializer(serializers.Serializer): class ProductSubtypeDocumentSerializer(serializers.Serializer):
"""Product subtype serializer for ES Document.""" """Product subtype serializer for ES Document."""
@ -149,6 +162,8 @@ class NewsDocumentSerializer(DocumentSerializer):
class EstablishmentDocumentSerializer(DocumentSerializer): class EstablishmentDocumentSerializer(DocumentSerializer):
"""Establishment document serializer.""" """Establishment document serializer."""
establishment_type = EstablishmentTypeSerializer()
establishment_subtypes = EstablishmentTypeSerializer(many=True)
address = AddressDocumentSerializer(allow_null=True) address = AddressDocumentSerializer(allow_null=True)
tags = TagsDocumentSerializer(many=True) tags = TagsDocumentSerializer(many=True)
schedule = ScheduleDocumentSerializer(many=True, allow_null=True) schedule = ScheduleDocumentSerializer(many=True, allow_null=True)

View File

@ -52,3 +52,17 @@ class TagsFilterSet(TagsBaseFilterSet):
model = models.Tag model = models.Tag
fields = ('type',) fields = ('type',)
# TMP TODO remove it later
# Временный хардкод для демонстрации 4 ноября, потом удалить!
def filter_by_type(self, queryset, name, value):
""" Overrides base filter. Temporary decision"""
if not (settings.NEWS_CHOSEN_TAGS and settings.ESTABLISHMENT_CHOSEN_TAGS):
return super().filter_by_type(queryset, name, value)
queryset = models.Tag.objects
if self.NEWS in value:
queryset = queryset.for_news().filter(value__in=settings.NEWS_CHOSEN_TAGS).distinct('value')
if self.ESTABLISHMENT in value:
queryset = queryset.for_establishments().filter(value__in=settings.ESTABLISHMENT_CHOSEN_TAGS).distinct(
'value')
return queryset

View File

@ -23,6 +23,23 @@ class ChosenTagsView(generics.ListAPIView, viewsets.GenericViewSet):
.filter(id__in=result_tags_ids) \ .filter(id__in=result_tags_ids) \
.order_by_priority() .order_by_priority()
def list(self, request, *args, **kwargs):
# TMP TODO remove it later
# Временный хардкод для демонстрации > 15 ноября, потом удалить!
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
result_list = serializer.data
if request.query_params.get('type') and (settings.ESTABLISHMENT_CHOSEN_TAGS or settings.NEWS_CHOSEN_TAGS):
ordered_list = settings.ESTABLISHMENT_CHOSEN_TAGS if request.query_params.get('type') == 'establishment' else settings.NEWS_CHOSEN_TAGS
result_list = sorted(result_list, key=lambda x: ordered_list.index(x['index_name']))
return Response(result_list)
# User`s views & viewsets # User`s views & viewsets
class TagCategoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): class TagCategoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):

View File

@ -1201,4 +1201,4 @@ class NewsletterSubscriber(MigrateMixin):
class Meta: class Meta:
managed = False managed = False
db_table = 'newsletter_subscriber' db_table = 'newsletter_subscriptions'

View File

@ -1,4 +1,6 @@
from rest_framework import serializers from rest_framework import serializers
from account.models import User
from notification.models import Subscriber from notification.models import Subscriber
@ -44,36 +46,33 @@ class NewsletterSubscriberSerializer(serializers.Serializer):
email_address__locale = serializers.CharField(allow_null=True) email_address__locale = serializers.CharField(allow_null=True)
created_at = serializers.DateTimeField(format='%m-%d-%Y %H:%M:%S') created_at = serializers.DateTimeField(format='%m-%d-%Y %H:%M:%S')
# def validate(self, data): def validate(self, data):
# data.update({ data.update({
# 'reviewer': self.get_reviewer(data), 'old_id': data.pop('id'),
# 'status': Review.READY if data['aasm_state'] == 'published' else Review.TO_INVESTIGATE, 'email': data.pop('email_address__email'),
# 'published_at': data.pop('created_at'), 'ip_address': data.pop('email_address__ip'),
# 'old_id': data.pop('id'), 'country_code': data.pop('email_address__country_code'),
# 'content_object': self.get_establishment(data), 'locale': data.pop('email_address__locale'),
# }) 'created': data.pop('created_at'),
# data.pop('reviewer_id') 'user_id': self.get_user(data),
# data.pop('establishment_id') })
# data.pop('aasm_state') data.pop('email_address__account_id')
# return data return data
#
# def create(self, validated_data): # def create(self, validated_data):
# obj, _ = Review.objects.update_or_create( # obj, _ = Review.objects.update_or_create(
# old_id=validated_data['old_id'], # old_id=validated_data['old_id'],
# defaults=validated_data, # defaults=validated_data,
# ) # )
# return obj # return obj
#
# @staticmethod @staticmethod
# def get_reviewer(data): def get_user(data):
# user = User.objects.filter(old_id=data['reviewer_id']).first()
# if not user: if not data['email_address__account_id']:
# raise ValueError(f"User account not found with old_id {data['reviewer_id']}") return None
# return user
# user = User.objects.filter(old_id=data['email_address__account_id']).first()
# @staticmethod if not user:
# def get_establishment(data): raise ValueError(f"User account not found with old_id {data['email_address__account_id']}")
# establishment = Establishment.objects.filter(old_id=data['establishment_id']).first() return user.id
# if not establishment:
# raise ValueError(f"Establishment not found with old_id {data['establishment_id']}: ")
# return establishment

View File

@ -487,3 +487,9 @@ PHONENUMBER_DB_FORMAT = 'NATIONAL'
PHONENUMBER_DEFAULT_REGION = "FR" PHONENUMBER_DEFAULT_REGION = "FR"
FALLBACK_LOCALE = 'en-GB' FALLBACK_LOCALE = 'en-GB'
# TMP TODO remove it later
# Временный хардкод для демонстрации > 15 ноября, потом удалить!
CAROUSEL_ITEMS = [230, 231, 232]
ESTABLISHMENT_CHOSEN_TAGS = ['gastronomic', 'en_vogue', 'terrace', 'streetfood', 'business', 'bar_cocktail', 'brunch', 'pop']
NEWS_CHOSEN_TAGS = ['eat', 'drink', 'cook', 'style', 'international', 'event', 'partnership']

View File

@ -9,7 +9,7 @@ urlpatterns = [
path('tags/', include('tag.urls.mobile')), path('tags/', include('tag.urls.mobile')),
path('timetables/', include('timetable.urls.mobile')), path('timetables/', include('timetable.urls.mobile')),
# path('account/', include('account.urls.web')), # path('account/', include('account.urls.web')),
# path('advertisement/', include('advertisement.urls.web')), path('re_blocks/', include('advertisement.urls.mobile')),
# path('collection/', include('collection.urls.web')), # path('collection/', include('collection.urls.web')),
# path('establishments/', include('establishment.urls.web')), # path('establishments/', include('establishment.urls.web')),
path('news/', include('news.urls.mobile')), path('news/', include('news.urls.mobile')),

View File

@ -36,4 +36,5 @@ urlpatterns = [
path('favorites/', include('favorites.urls')), path('favorites/', include('favorites.urls')),
path('timetables/', include('timetable.urls.web')), path('timetables/', include('timetable.urls.web')),
path('products/', include('product.urls.web')), path('products/', include('product.urls.web')),
] ]