Merge branch 'develop' into feature/guides

This commit is contained in:
Anatoly 2019-12-19 18:18:39 +03:00
commit 021d608bdc
18 changed files with 239 additions and 69 deletions

View File

@ -1,4 +1,5 @@
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from drf_yasg.utils import swagger_auto_schema
from rest_framework import generics, permissions, status, serializers from rest_framework import generics, permissions, status, serializers
from rest_framework.response import Response from rest_framework.response import Response
@ -96,6 +97,13 @@ class CreatePendingBooking(generics.CreateAPIView):
permission_classes = (permissions.AllowAny,) permission_classes = (permissions.AllowAny,)
serializer_class = PendingBookingSerializer serializer_class = PendingBookingSerializer
@swagger_auto_schema(operation_description="Request body params\n\n"
"IN GUESTONLINE (type:G): {"
"'restaurant_id', 'booking_time', "
"'booking_date', 'booked_persons_number'}\n"
"IN LASTABLE (type:L): {'booking_time', "
"'booked_persons_number', 'offer_id' (Req), "
"'email', 'phone', 'first_name', 'last_name'}")
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
data = request.data.copy() data = request.data.copy()
if data.get('type') == Booking.LASTABLE and data.get("offer_id") is None: if data.get('type') == Booking.LASTABLE and data.get("offer_id") is None:
@ -135,6 +143,10 @@ class UpdatePendingBooking(generics.UpdateAPIView):
permission_classes = (permissions.AllowAny,) permission_classes = (permissions.AllowAny,)
serializer_class = UpdateBookingSerializer serializer_class = UpdateBookingSerializer
@swagger_auto_schema(operation_description="Request body params\n\n"
"Required: 'email', 'phone', 'last_name', "
"'first_name', 'country_code', 'pending_booking_id',"
"Not req: 'note'")
def patch(self, request, *args, **kwargs): def patch(self, request, *args, **kwargs):
instance = self.get_object() instance = self.get_object()
data = request.data.copy() data = request.data.copy()

View File

@ -1,5 +1,5 @@
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from tqdm import tqdm
from establishment.models import Establishment from establishment.models import Establishment
from transfer.models import Reviews, ReviewTexts from transfer.models import Reviews, ReviewTexts
@ -22,7 +22,7 @@ class Command(BaseCommand):
'updated_at', 'updated_at',
) )
for r_id, establishment_id, new_date in queryset: for r_id, establishment_id, new_date in tqdm(queryset):
try: try:
review_id, date = valid_reviews[establishment_id] review_id, date = valid_reviews[establishment_id]
except KeyError: except KeyError:
@ -41,7 +41,7 @@ class Command(BaseCommand):
'text', 'text',
) )
for es_id, locale, text in text_qs: for es_id, locale, text in tqdm(text_qs):
establishment = Establishment.objects.filter(old_id=es_id).first() establishment = Establishment.objects.filter(old_id=es_id).first()
if establishment: if establishment:
description = establishment.description description = establishment.description
@ -53,7 +53,7 @@ class Command(BaseCommand):
count += 1 count += 1
# Если нет en-GB в поле # Если нет en-GB в поле
for establishment in Establishment.objects.filter(old_id__isnull=False): for establishment in tqdm(Establishment.objects.filter(old_id__isnull=False)):
description = establishment.description description = establishment.description
if len(description) and 'en-GB' not in description: if len(description) and 'en-GB' not in description:
description.update({ description.update({

View File

@ -0,0 +1,45 @@
from django.core.management.base import BaseCommand
from tqdm import tqdm
from establishment.models import Establishment
from transfer.models import Descriptions
class Command(BaseCommand):
help = """Add description to establishment from old db."""
def handle(self, *args, **kwarg):
establishments = Establishment.objects.exclude(old_id__isnull=True)
self.stdout.write(self.style.WARNING(f'Clear old descriptions'))
for item in tqdm(establishments):
item.description = None
item.save()
queryset = Descriptions.objects.filter(
establishment_id__in=list(establishments.values_list('old_id', flat=True)),
).values_list('establishment_id', 'locale', 'text')
self.stdout.write(self.style.WARNING(f'Update new description'))
for establishment_id, locale, text in tqdm(queryset):
establishment = Establishment.objects.filter(old_id=establishment_id).first()
if establishment:
if establishment.description:
establishment.description.update({
locale: text
})
else:
establishment.description = {locale: text}
establishment.save()
self.stdout.write(self.style.WARNING(f'Update en-GB description'))
for establishment in tqdm(establishments.filter(description__isnull=False)):
description = establishment.description
if len(description) and 'en-GB' not in description:
description.update({
'en-GB': next(iter(description.values()))
})
establishment.description = description
establishment.save()
self.stdout.write(self.style.WARNING(f'Done'))

View File

@ -90,7 +90,6 @@ class CitySerializer(serializers.ModelSerializer):
fields = [ fields = [
'id', 'id',
'name', 'name',
'code',
'region', 'region',
'region_id', 'region_id',
'country_id', 'country_id',

View File

@ -1,4 +1,5 @@
"""Location app views.""" """Location app views."""
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import generics from rest_framework import generics
from location import models, serializers from location import models, serializers
@ -11,6 +12,7 @@ from utils.serializers import ImageBaseSerializer
from location import filters from location import filters
# Address # Address
@ -18,29 +20,36 @@ class AddressListCreateView(common.AddressViewMixin, generics.ListCreateAPIView)
"""Create view for model Address.""" """Create view for model Address."""
serializer_class = serializers.AddressDetailSerializer serializer_class = serializers.AddressDetailSerializer
queryset = models.Address.objects.all() queryset = models.Address.objects.all()
permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin] permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin]
class AddressRUDView(common.AddressViewMixin, generics.RetrieveUpdateDestroyAPIView): class AddressRUDView(common.AddressViewMixin, generics.RetrieveUpdateDestroyAPIView):
"""RUD view for model Address.""" """RUD view for model Address."""
serializer_class = serializers.AddressDetailSerializer serializer_class = serializers.AddressDetailSerializer
queryset = models.Address.objects.all() queryset = models.Address.objects.all()
permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin] permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin]
# City # City
class CityListCreateView(common.CityViewMixin, generics.ListCreateAPIView): class CityListCreateView(common.CityViewMixin, generics.ListCreateAPIView):
"""Create view for model City.""" """Create view for model City."""
serializer_class = serializers.CitySerializer serializer_class = serializers.CitySerializer
permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin] permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin]
queryset = models.City.objects.all() # queryset = models.City.objects.all()
filter_class = filters.CityBackFilter filter_class = filters.CityBackFilter
def get_queryset(self):
"""Overridden method 'get_queryset'."""
qs = models.City.objects.all()
if self.request.country_code:
qs = qs.by_country_code(self.request.country_code)
return qs
class CityListSearchView(common.CityViewMixin, generics.ListCreateAPIView): class CityListSearchView(common.CityViewMixin, generics.ListCreateAPIView):
"""Create view for model City.""" """Create view for model City."""
serializer_class = serializers.CitySerializer serializer_class = serializers.CitySerializer
permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin] permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin]
queryset = models.City.objects.all() queryset = models.City.objects.all()
filter_class = filters.CityBackFilter filter_class = filters.CityBackFilter
pagination_class = None pagination_class = None
@ -49,14 +58,14 @@ class CityListSearchView(common.CityViewMixin, generics.ListCreateAPIView):
class CityRUDView(common.CityViewMixin, generics.RetrieveUpdateDestroyAPIView): class CityRUDView(common.CityViewMixin, generics.RetrieveUpdateDestroyAPIView):
"""RUD view for model City.""" """RUD view for model City."""
serializer_class = serializers.CitySerializer serializer_class = serializers.CitySerializer
permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin] permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin]
class CityGalleryCreateDestroyView(common.CityViewMixin, class CityGalleryCreateDestroyView(common.CityViewMixin,
CreateDestroyGalleryViewMixin): CreateDestroyGalleryViewMixin):
"""Resource for a create gallery for product for back-office users.""" """Resource for a create gallery for product for back-office users."""
serializer_class = serializers.CityGallerySerializer serializer_class = serializers.CityGallerySerializer
permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin] permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin]
def get_object(self): def get_object(self):
""" """
@ -77,7 +86,7 @@ class CityGalleryListView(common.CityViewMixin,
generics.ListAPIView): generics.ListAPIView):
"""Resource for returning gallery for product for back-office users.""" """Resource for returning gallery for product for back-office users."""
serializer_class = ImageBaseSerializer serializer_class = ImageBaseSerializer
permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin] permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin]
def get_object(self): def get_object(self):
"""Override get_object method.""" """Override get_object method."""
@ -99,13 +108,18 @@ class RegionListCreateView(common.RegionViewMixin, generics.ListCreateAPIView):
"""Create view for model Region""" """Create view for model Region"""
pagination_class = None pagination_class = None
serializer_class = serializers.RegionSerializer serializer_class = serializers.RegionSerializer
permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin] permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin]
filter_backends = (DjangoFilterBackend,)
ordering_fields = '__all__'
filterset_fields = (
'country',
)
class RegionRUDView(common.RegionViewMixin, generics.RetrieveUpdateDestroyAPIView): class RegionRUDView(common.RegionViewMixin, generics.RetrieveUpdateDestroyAPIView):
"""Retrieve view for model Region""" """Retrieve view for model Region"""
serializer_class = serializers.RegionSerializer serializer_class = serializers.RegionSerializer
permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin] permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin]
# Country # Country
@ -114,11 +128,11 @@ class CountryListCreateView(generics.ListCreateAPIView):
queryset = models.Country.objects.all() queryset = models.Country.objects.all()
serializer_class = serializers.CountryBackSerializer serializer_class = serializers.CountryBackSerializer
pagination_class = None pagination_class = None
permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin] permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin]
class CountryRUDView(generics.RetrieveUpdateDestroyAPIView): class CountryRUDView(generics.RetrieveUpdateDestroyAPIView):
"""RUD view for model Country.""" """RUD view for model Country."""
serializer_class = serializers.CountryBackSerializer serializer_class = serializers.CountryBackSerializer
permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin] permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin]
queryset = models.Country.objects.all() queryset = models.Country.objects.all()

View File

@ -210,25 +210,6 @@ class CarouselQuerySet(models.QuerySet):
"""Filter collection by country code.""" """Filter collection by country code."""
return self.filter(country__code=code) return self.filter(country__code=code)
def create_or_destroy(self, instance_to_bind, country):
"""Creates or destroys Carousel instance depending on instance fields"""
toggle = True
kwargs = {
'content_type': ContentType.objects.get_for_model(instance_to_bind),
'object_id': instance_to_bind.pk,
'country': country,
}
if toggle is None:
return
elif toggle:
kwargs.update({
'is_parse': True,
'active': True,
})
self.create(**kwargs)
else:
self.filter(**kwargs).delete()
class Carousel(models.Model): class Carousel(models.Model):
"""Carousel model.""" """Carousel model."""

View File

@ -6,7 +6,6 @@ from rest_framework.response import Response
from main import methods, models, serializers from main import methods, models, serializers
# #
# class FeatureViewMixin: # class FeatureViewMixin:
# """Feature view mixin.""" # """Feature view mixin."""
@ -86,8 +85,13 @@ class DetermineLocation(generics.GenericAPIView):
longitude, latitude = methods.determine_coordinates(request) longitude, latitude = methods.determine_coordinates(request)
city = methods.determine_user_city(request) city = methods.determine_user_city(request)
country_name = methods.determine_country_name(request) country_name = methods.determine_country_name(request)
country_code = methods.determine_country_code(request)
if longitude and latitude and city and country_name: if longitude and latitude and city and country_name:
return Response(data={'latitude': latitude, 'longitude': longitude, return Response(data={
'city': city, 'country_name': country_name}) 'latitude': latitude,
'longitude': longitude,
'city': city,
'country_name': country_name,
'country_code': country_code,
})
raise Http404 raise Http404

View File

@ -72,4 +72,6 @@ class NewsListFilterSet(filters.FilterSet):
return queryset return queryset
def sort_by_field(self, queryset, name, value): def sort_by_field(self, queryset, name, value):
if value == self.SORT_BY_START_CHOICE:
return queryset.order_by('-publication_date', '-publication_time')
return queryset.order_by(f'-{value}') return queryset.order_by(f'-{value}')

View File

@ -0,0 +1,38 @@
# Generated by Django 2.2.7 on 2019-12-18 14:37
from django.db import migrations, models
def fill_publication_date_and_time(apps, schema_editor):
News = apps.get_model('news', 'News')
for news in News.objects.all():
if news.start is not None:
news.publication_date = news.start.date()
news.publication_time = news.start.time()
news.save()
class Migration(migrations.Migration):
dependencies = [
('news', '0045_news_must_of_the_week'),
]
operations = [
migrations.AddField(
model_name='news',
name='publication_date',
field=models.DateField(blank=True, help_text='date since when news item is published', null=True, verbose_name='News publication date'),
),
migrations.AddField(
model_name='news',
name='publication_time',
field=models.TimeField(blank=True, help_text='time since when news item is published', null=True, verbose_name='News publication time'),
),
migrations.AlterField(
model_name='news',
name='must_of_the_week',
field=models.BooleanField(default=False, verbose_name='Show in the carousel'),
),
migrations.RunPython(fill_publication_date_and_time, migrations.RunPython.noop),
]

View File

@ -0,0 +1,17 @@
# Generated by Django 2.2.7 on 2019-12-18 16:20
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('news', '0046_auto_20191218_1437'),
]
operations = [
migrations.RemoveField(
model_name='news',
name='start',
),
]

View File

@ -0,0 +1,17 @@
# Generated by Django 2.2.7 on 2019-12-19 13:47
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('news', '0047_remove_news_start'),
]
operations = [
migrations.RemoveField(
model_name='news',
name='must_of_the_week',
),
]

View File

@ -3,6 +3,7 @@ import uuid
from django.conf import settings from django.conf import settings
from django.contrib.contenttypes import fields as generic from django.contrib.contenttypes import fields as generic
from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.fields import HStoreField from django.contrib.postgres.fields import HStoreField
from django.db import models from django.db import models
from django.db.models import Case, When from django.db.models import Case, When
@ -10,11 +11,13 @@ from django.utils import timezone
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from rest_framework.reverse import reverse from rest_framework.reverse import reverse
from main.models import Carousel
from rating.models import Rating, ViewCount from rating.models import Rating, ViewCount
from utils.models import (BaseAttributes, TJSONField, TranslatedFieldsMixin, HasTagsMixin, from utils.models import (BaseAttributes, TJSONField, TranslatedFieldsMixin, HasTagsMixin,
ProjectBaseMixin, GalleryModelMixin, IntermediateGalleryModelMixin, ProjectBaseMixin, GalleryModelMixin, IntermediateGalleryModelMixin,
FavoritesMixin) FavoritesMixin)
from utils.querysets import TranslationQuerysetMixin from utils.querysets import TranslationQuerysetMixin
from datetime import datetime
class Agenda(ProjectBaseMixin, TranslatedFieldsMixin): class Agenda(ProjectBaseMixin, TranslatedFieldsMixin):
@ -64,7 +67,7 @@ class NewsQuerySet(TranslationQuerysetMixin):
def sort_by_start(self): def sort_by_start(self):
"""Return qs sorted by start DESC""" """Return qs sorted by start DESC"""
return self.order_by('-start') return self.order_by('-publication_date', '-publication_time')
def rating_value(self): def rating_value(self):
return self.annotate(rating=models.Count('ratings__ip', distinct=True)) return self.annotate(rating=models.Count('ratings__ip', distinct=True))
@ -99,9 +102,13 @@ class NewsQuerySet(TranslationQuerysetMixin):
def published(self): def published(self):
"""Return only published news""" """Return only published news"""
now = timezone.now() now = timezone.now()
return self.filter(models.Q(models.Q(end__gte=now) | date_now = now.date()
time_now = now.time()
return self.exclude(models.Q(publication_date__isnull=True) | models.Q(publication_time__isnull=True)). \
filter(models.Q(models.Q(end__gte=now) |
models.Q(end__isnull=True)), models.Q(end__isnull=True)),
state__in=self.model.PUBLISHED_STATES, start__lte=now) state__in=self.model.PUBLISHED_STATES, publication_date__lte=date_now,
publication_time__lte=time_now)
# todo: filter by best score # todo: filter by best score
# todo: filter by country? # todo: filter by country?
@ -114,7 +121,7 @@ class NewsQuerySet(TranslationQuerysetMixin):
return self.model.objects.exclude(pk=news.pk).published(). \ return self.model.objects.exclude(pk=news.pk).published(). \
annotate_in_favorites(user). \ 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().sort_by_start()
def annotate_in_favorites(self, user): def annotate_in_favorites(self, user):
"""Annotate flag in_favorites""" """Annotate flag in_favorites"""
@ -185,8 +192,10 @@ class News(GalleryModelMixin, BaseAttributes, TranslatedFieldsMixin, HasTagsMixi
locale_to_description_is_active = HStoreField(null=True, default=dict, blank=True, locale_to_description_is_active = HStoreField(null=True, default=dict, blank=True,
verbose_name=_('Is description for certain locale active'), verbose_name=_('Is description for certain locale active'),
help_text='{"en-GB": true, "fr-FR": false}') help_text='{"en-GB": true, "fr-FR": false}')
start = models.DateTimeField(blank=True, null=True, default=None, publication_date = models.DateField(blank=True, null=True, verbose_name=_('News publication date'),
verbose_name=_('Start')) help_text=_('date since when news item is published'))
publication_time = models.TimeField(blank=True, null=True, verbose_name=_('News publication time'),
help_text=_('time since when news item is published'))
end = models.DateTimeField(blank=True, null=True, default=None, end = models.DateTimeField(blank=True, null=True, default=None,
verbose_name=_('End')) verbose_name=_('End'))
slugs = HStoreField(null=True, blank=True, default=dict, slugs = HStoreField(null=True, blank=True, default=dict,
@ -223,7 +232,6 @@ class News(GalleryModelMixin, BaseAttributes, TranslatedFieldsMixin, HasTagsMixi
verbose_name=_('Duplication datetime')) verbose_name=_('Duplication datetime'))
duplication_uuid = models.UUIDField(default=uuid.uuid4, editable=True, unique=False, duplication_uuid = models.UUIDField(default=uuid.uuid4, editable=True, unique=False,
verbose_name=_('Field to detect doubles')) verbose_name=_('Field to detect doubles'))
must_of_the_week = models.BooleanField(default=False, verbose_name=_('Show in the carousel'))
objects = NewsQuerySet.as_manager() objects = NewsQuerySet.as_manager()
class Meta: class Meta:
@ -244,6 +252,24 @@ class News(GalleryModelMixin, BaseAttributes, TranslatedFieldsMixin, HasTagsMixi
self.duplication_date = timezone.now() self.duplication_date = timezone.now()
self.save() self.save()
@property
def must_of_the_week(self) -> bool:
"""Detects whether current item in carousel"""
kwargs = {
'content_type': ContentType.objects.get_for_model(self),
'object_id': self.pk,
'country': self.country,
}
return Carousel.objects.filter(**kwargs).exists()
@property
def publication_datetime(self):
"""Represents datetime object combined from `publication_date` & `publication_time` fields"""
try:
return datetime.combine(date=self.publication_date, time=self.publication_time)
except TypeError:
return None
@property @property
def duplicates(self): def duplicates(self):
"""Duplicates for this news item excluding same country code labeled""" """Duplicates for this news item excluding same country code labeled"""

View File

@ -128,6 +128,7 @@ class NewsDetailSerializer(NewsBaseSerializer):
state_display = serializers.CharField(source='get_state_display', state_display = serializers.CharField(source='get_state_display',
read_only=True) read_only=True)
gallery = ImageBaseSerializer(read_only=True, source='crop_gallery', many=True) gallery = ImageBaseSerializer(read_only=True, source='crop_gallery', many=True)
start = serializers.DateTimeField(source='publication_datetime', read_only=True)
class Meta(NewsBaseSerializer.Meta): class Meta(NewsBaseSerializer.Meta):
"""Meta class.""" """Meta class."""
@ -186,11 +187,13 @@ class NewsBackOfficeBaseSerializer(NewsBaseSerializer):
'is_published', 'is_published',
'duplication_date', 'duplication_date',
'must_of_the_week', 'must_of_the_week',
'publication_date',
'publication_time',
) )
extra_kwargs = { extra_kwargs = {
'backoffice_title': {'allow_null': False},
'duplication_date': {'read_only': True}, 'duplication_date': {'read_only': True},
'locale_to_description_is_active': {'allow_null': False} 'locale_to_description_is_active': {'allow_null': False},
'must_of_the_week': {'read_only': True},
} }
def create(self, validated_data): def create(self, validated_data):
@ -200,9 +203,7 @@ class NewsBackOfficeBaseSerializer(NewsBaseSerializer):
slugs__values__contains=list(slugs.values()) slugs__values__contains=list(slugs.values())
).exists(): ).exists():
raise serializers.ValidationError({'slugs': _('News with this slug already exists.')}) raise serializers.ValidationError({'slugs': _('News with this slug already exists.')})
instance = super().create(validated_data) return super().create(validated_data)
Carousel.objects.create_or_destroy(instance, instance.address.city.country)
return instance
def update(self, instance, validated_data): def update(self, instance, validated_data):
slugs = validated_data.get('slugs') slugs = validated_data.get('slugs')
@ -211,10 +212,7 @@ class NewsBackOfficeBaseSerializer(NewsBaseSerializer):
slugs__values__contains=list(slugs.values()) slugs__values__contains=list(slugs.values())
).exclude(pk=instance.pk).exists(): ).exclude(pk=instance.pk).exists():
raise serializers.ValidationError({'slugs': _('News with this slug already exists.')}) raise serializers.ValidationError({'slugs': _('News with this slug already exists.')})
ret = super().update(instance, validated_data) return super().update(instance, validated_data)
if ret.must_of_the_week != instance.must_of_the_week:
Carousel.objects.create_or_destroy(instance, instance.address.city.country)
return ret
class NewsBackOfficeDuplicationInfoSerializer(serializers.ModelSerializer): class NewsBackOfficeDuplicationInfoSerializer(serializers.ModelSerializer):
@ -282,8 +280,8 @@ class NewsBackOfficeGallerySerializer(serializers.ModelSerializer):
return self.context.get('request').parser_context.get('kwargs') return self.context.get('request').parser_context.get('kwargs')
def create(self, validated_data): def create(self, validated_data):
news_pk = self.get_request_kwargs().get('pk') news_pk = self.request_kwargs.get('pk')
image_id = self.get_request_kwargs().get('image_id') image_id = self.request_kwargs.get('image_id')
qs = models.NewsGallery.objects.filter(image_id=image_id, news_id=news_pk) qs = models.NewsGallery.objects.filter(image_id=image_id, news_id=news_pk)
instance = qs.first() instance = qs.first()
if instance: if instance:
@ -362,7 +360,12 @@ class NewsCarouselCreateSerializer(CarouselCreateSerializer):
def create(self, validated_data, *args, **kwargs): def create(self, validated_data, *args, **kwargs):
validated_data.update({ validated_data.update({
'content_object': validated_data.pop('news') 'country': validated_data['news'].country
})
validated_data.update({
'content_object': validated_data.pop('news'),
'is_parse': True,
'active': True,
}) })
return super().create(validated_data) return super().create(validated_data)

View File

@ -14,5 +14,5 @@ urlpatterns = [
path('<int:pk>/gallery/<int:image_id>/', views.NewsBackOfficeGalleryCreateDestroyView.as_view(), path('<int:pk>/gallery/<int:image_id>/', views.NewsBackOfficeGalleryCreateDestroyView.as_view(),
name='gallery-create-destroy'), name='gallery-create-destroy'),
path('<int:pk>/carousels/', views.NewsCarouselCreateDestroyView.as_view(), name='create-destroy-carousels'), path('<int:pk>/carousels/', views.NewsCarouselCreateDestroyView.as_view(), name='create-destroy-carousels'),
path('<int:pk>/clone/<str:country_code>', views.NewsCloneView.as_view(), name='create-destroy-carousels'), path('<int:pk>/clone/<str:country_code>', views.NewsCloneView.as_view(), name='clone-news-item'),
] ]

View File

@ -22,7 +22,7 @@ class NewsMixinView:
qs = models.News.objects.published() \ qs = models.News.objects.published() \
.with_base_related() \ .with_base_related() \
.annotate_in_favorites(self.request.user) \ .annotate_in_favorites(self.request.user) \
.order_by('-is_highlighted', '-start') .order_by('-is_highlighted', '-publication_date', '-publication_time')
country_code = self.request.country_code country_code = self.request.country_code
if country_code: if country_code:
@ -31,9 +31,9 @@ class NewsMixinView:
else: else:
qs = qs.by_country_code(country_code) qs = qs.by_country_code(country_code)
locale = kwargs.get('locale') # locale = kwargs.get('locale')
if locale: # if locale:
qs = qs.by_locale(locale) # qs = qs.by_locale(locale)
return qs return qs

View File

@ -45,7 +45,7 @@ class NewsDocument(Document):
}, },
multi=True) multi=True)
favorites_for_users = fields.ListField(field=fields.IntegerField()) favorites_for_users = fields.ListField(field=fields.IntegerField())
start = fields.DateField(attr='start') start = fields.DateField(attr='publication_datetime')
has_any_desc_active = fields.BooleanField() has_any_desc_active = fields.BooleanField()
def prepare_slugs(self, instance): def prepare_slugs(self, instance):

View File

@ -1,13 +1,15 @@
"""Search indexes app views.""" """Search indexes app views."""
from rest_framework import permissions
from django_elasticsearch_dsl_drf import constants from django_elasticsearch_dsl_drf import constants
from django_elasticsearch_dsl_drf.filter_backends import ( from django_elasticsearch_dsl_drf.filter_backends import (
FilteringFilterBackend, FilteringFilterBackend,
GeoSpatialOrderingFilterBackend, GeoSpatialOrderingFilterBackend,
OrderingFilterBackend, OrderingFilterBackend,
) )
from elasticsearch_dsl import TermsFacet
from django_elasticsearch_dsl_drf.viewsets import BaseDocumentViewSet from django_elasticsearch_dsl_drf.viewsets import BaseDocumentViewSet
from elasticsearch_dsl import TermsFacet
from rest_framework import permissions
from product.models import Product
from search_indexes import serializers, filters, utils from search_indexes import serializers, filters, utils
from search_indexes.documents import EstablishmentDocument, NewsDocument from search_indexes.documents import EstablishmentDocument, NewsDocument
from search_indexes.documents.product import ProductDocument from search_indexes.documents.product import ProductDocument
@ -346,6 +348,12 @@ class ProductDocumentViewSet(BaseDocumentViewSet):
# GeoSpatialOrderingFilterBackend, # GeoSpatialOrderingFilterBackend,
] ]
def get_queryset(self):
qs = super(ProductDocumentViewSet, self).get_queryset()
qs = qs.filter('match', state=Product.PUBLISHED)
return qs
ordering_fields = { ordering_fields = {
'created': { 'created': {
'field': 'created', 'field': 'created',

View File

@ -77,7 +77,11 @@ class EstablishmentSerializer(serializers.ModelSerializer):
schedules = validated_data.pop('schedules') schedules = validated_data.pop('schedules')
subtypes = [validated_data.pop('subtype', None)] subtypes = [validated_data.pop('subtype', None)]
establishment = Establishment.objects.create(**validated_data) # establishment = Establishment.objects.create(**validated_data)
establishment, _ = Establishment.objects.update_or_create(
old_id=validated_data['old_id'],
defaults=validated_data,
)
if email: if email:
ContactEmail.objects.get_or_create( ContactEmail.objects.get_or_create(
email=email, email=email,