Merge branch 'develop' into feature/guides
This commit is contained in:
commit
2401763e6c
|
|
@ -17,8 +17,8 @@ class CollectionViewMixin(generics.GenericAPIView):
|
|||
def get_queryset(self):
|
||||
"""Override get_queryset method."""
|
||||
return models.Collection.objects.published() \
|
||||
.by_country_code(code=self.request.country_code) \
|
||||
.order_by('-on_top', '-modified')
|
||||
.by_country_code(code=self.request.country_code) \
|
||||
.order_by('-on_top', '-created')
|
||||
|
||||
|
||||
class GuideViewMixin(generics.GenericAPIView):
|
||||
|
|
@ -39,7 +39,7 @@ class CollectionHomePageView(CollectionListView):
|
|||
def get_queryset(self):
|
||||
"""Override get_queryset."""
|
||||
return super(CollectionHomePageView, self).get_queryset() \
|
||||
.filter_all_related_gt(3)
|
||||
.filter_all_related_gt(3)
|
||||
|
||||
|
||||
class CollectionDetailView(CollectionViewMixin, generics.RetrieveAPIView):
|
||||
|
|
|
|||
|
|
@ -37,6 +37,13 @@ def determine_country_code(request):
|
|||
return country_code.lower()
|
||||
|
||||
|
||||
def determine_country_name(request):
|
||||
"""Determine country name."""
|
||||
META = request.META
|
||||
return META.get('X-GeoIP-Country-Name',
|
||||
META.get('HTTP_X_GEOIP_COUNTRY_NAME'))
|
||||
|
||||
|
||||
def determine_coordinates(request):
|
||||
META = request.META
|
||||
longitude = META.get('X-GeoIP-Longitude',
|
||||
|
|
|
|||
|
|
@ -210,6 +210,25 @@ class CarouselQuerySet(models.QuerySet):
|
|||
"""Filter collection by country 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):
|
||||
"""Carousel model."""
|
||||
|
|
@ -279,6 +298,11 @@ class Carousel(models.Model):
|
|||
|
||||
@property
|
||||
def slug(self):
|
||||
if hasattr(self.content_object, 'slugs'):
|
||||
try:
|
||||
return next(iter(self.content_object.slugs.values()))
|
||||
except StopIteration:
|
||||
return None
|
||||
if hasattr(self.content_object, 'slug'):
|
||||
return self.content_object.slug
|
||||
|
||||
|
|
|
|||
|
|
@ -85,8 +85,9 @@ class DetermineLocation(generics.GenericAPIView):
|
|||
def get(self, request, *args, **kwargs):
|
||||
longitude, latitude = methods.determine_coordinates(request)
|
||||
city = methods.determine_user_city(request)
|
||||
if longitude and latitude and city:
|
||||
return Response(data={'latitude': latitude, 'longitude': longitude, 'city': city})
|
||||
else:
|
||||
raise Http404
|
||||
country_name = methods.determine_country_name(request)
|
||||
if longitude and latitude and city and country_name:
|
||||
return Response(data={'latitude': latitude, 'longitude': longitude,
|
||||
'city': city, 'country_name': country_name})
|
||||
raise Http404
|
||||
|
||||
|
|
|
|||
18
apps/news/migrations/0045_news_must_of_the_week.py
Normal file
18
apps/news/migrations/0045_news_must_of_the_week.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 2.2.7 on 2019-12-17 17:59
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('news', '0044_auto_20191216_2044'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='news',
|
||||
name='must_of_the_week',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
||||
|
|
@ -223,6 +223,7 @@ class News(GalleryModelMixin, BaseAttributes, TranslatedFieldsMixin, HasTagsMixi
|
|||
verbose_name=_('Duplication datetime'))
|
||||
duplication_uuid = models.UUIDField(default=uuid.uuid4, editable=True, unique=False,
|
||||
verbose_name=_('Field to detect doubles'))
|
||||
must_of_the_week = models.BooleanField(default=False, verbose_name=_('Show in the carousel'))
|
||||
objects = NewsQuerySet.as_manager()
|
||||
|
||||
class Meta:
|
||||
|
|
@ -248,6 +249,11 @@ class News(GalleryModelMixin, BaseAttributes, TranslatedFieldsMixin, HasTagsMixi
|
|||
"""Duplicates for this news item excluding same country code labeled"""
|
||||
return News.objects.filter(duplication_uuid=self.duplication_uuid).exclude(country=self.country)
|
||||
|
||||
@property
|
||||
def has_any_desc_active(self):
|
||||
"""Detects whether news item has any active description"""
|
||||
return any(list(map(lambda v: v.lower() == 'true', self.locale_to_description_is_active.values())))
|
||||
|
||||
@property
|
||||
def is_publish(self):
|
||||
return self.state in self.PUBLISHED_STATES
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from rest_framework.fields import SerializerMethodField
|
|||
|
||||
from account.serializers.common import UserBaseSerializer
|
||||
from gallery.models import Image
|
||||
from main.models import SiteSettings
|
||||
from main.models import SiteSettings, Carousel
|
||||
from location import models as location_models
|
||||
from location.serializers import CountrySimpleSerializer, AddressBaseSerializer
|
||||
from news import models
|
||||
|
|
@ -185,6 +185,7 @@ class NewsBackOfficeBaseSerializer(NewsBaseSerializer):
|
|||
'locale_to_description_is_active',
|
||||
'is_published',
|
||||
'duplication_date',
|
||||
'must_of_the_week',
|
||||
)
|
||||
extra_kwargs = {
|
||||
'backoffice_title': {'allow_null': False},
|
||||
|
|
@ -199,7 +200,9 @@ class NewsBackOfficeBaseSerializer(NewsBaseSerializer):
|
|||
slugs__values__contains=list(slugs.values())
|
||||
).exists():
|
||||
raise serializers.ValidationError({'slugs': _('News with this slug already exists.')})
|
||||
return super().create(validated_data)
|
||||
instance = super().create(validated_data)
|
||||
Carousel.objects.create_or_destroy(instance, instance.address.city.country)
|
||||
return instance
|
||||
|
||||
def update(self, instance, validated_data):
|
||||
slugs = validated_data.get('slugs')
|
||||
|
|
@ -208,7 +211,10 @@ class NewsBackOfficeBaseSerializer(NewsBaseSerializer):
|
|||
slugs__values__contains=list(slugs.values())
|
||||
).exclude(pk=instance.pk).exists():
|
||||
raise serializers.ValidationError({'slugs': _('News with this slug already exists.')})
|
||||
return super().update(instance, validated_data)
|
||||
ret = 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):
|
||||
|
|
@ -380,5 +386,5 @@ class NewsCloneCreateSerializer(NewsBackOfficeBaseSerializer,
|
|||
new_country = get_object_or_404(location_models.Country, code=kwargs['country_code'])
|
||||
view_count_model = rating_models.ViewCount.objects.create(count=0)
|
||||
instance.create_duplicate(new_country, view_count_model)
|
||||
return instance
|
||||
return get_object_or_404(models.News, pk=kwargs['pk'])
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,8 @@ class NewsListView(NewsMixinView, generics.ListAPIView):
|
|||
'international_preferred': True,
|
||||
'locale': locale,
|
||||
})
|
||||
return super().get_queryset(*args, **kwargs)
|
||||
return super().get_queryset(*args, **kwargs)\
|
||||
.filter(locale_to_description_is_active__values__contains=['True'])
|
||||
|
||||
|
||||
class NewsDetailView(NewsMixinView, generics.RetrieveAPIView):
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from django.conf import settings
|
|||
from django_elasticsearch_dsl import Document, Index, fields
|
||||
from search_indexes.utils import OBJECT_FIELD_PROPERTIES
|
||||
from news import models
|
||||
from json import dumps
|
||||
|
||||
|
||||
NewsIndex = Index(settings.ELASTICSEARCH_INDEX_NAMES.get(__name__, 'news'))
|
||||
|
|
@ -17,7 +18,7 @@ class NewsDocument(Document):
|
|||
'name': fields.KeywordField()})
|
||||
title = fields.ObjectField(attr='title_indexing',
|
||||
properties=OBJECT_FIELD_PROPERTIES)
|
||||
slugs = fields.ObjectField(properties=OBJECT_FIELD_PROPERTIES)
|
||||
slugs = fields.KeywordField()
|
||||
backoffice_title = fields.TextField(analyzer='english')
|
||||
subtitle = fields.ObjectField(attr='subtitle_indexing',
|
||||
properties=OBJECT_FIELD_PROPERTIES)
|
||||
|
|
@ -45,9 +46,10 @@ class NewsDocument(Document):
|
|||
multi=True)
|
||||
favorites_for_users = fields.ListField(field=fields.IntegerField())
|
||||
start = fields.DateField(attr='start')
|
||||
has_any_desc_active = fields.BooleanField()
|
||||
|
||||
def prepare_slugs(self, instance):
|
||||
return {locale: instance.slugs.get(locale) for locale in OBJECT_FIELD_PROPERTIES}
|
||||
return dumps(instance.slugs or {})
|
||||
|
||||
class Django:
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ from news.serializers import NewsTypeSerializer
|
|||
from search_indexes.documents import EstablishmentDocument, NewsDocument
|
||||
from search_indexes.documents.product import ProductDocument
|
||||
from search_indexes.utils import get_translated_value
|
||||
from json import loads
|
||||
|
||||
|
||||
class TagsDocumentSerializer(serializers.Serializer):
|
||||
|
|
@ -243,7 +244,7 @@ class NewsDocumentSerializer(InFavoritesMixin, DocumentSerializer):
|
|||
|
||||
@staticmethod
|
||||
def get_slug(obj):
|
||||
return get_translated_value(obj.slugs)
|
||||
return get_translated_value(loads(obj.slugs))
|
||||
|
||||
@staticmethod
|
||||
def get_title_translated(obj):
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@ from utils.pagination import ESDocumentPagination
|
|||
class NewsDocumentViewSet(BaseDocumentViewSet):
|
||||
"""News document ViewSet."""
|
||||
|
||||
def get_queryset(self):
|
||||
qs = super(NewsDocumentViewSet, self).get_queryset()
|
||||
qs = qs.filter('match', has_any_desc_active=True)
|
||||
return qs
|
||||
|
||||
document = NewsDocument
|
||||
lookup_field = 'slug'
|
||||
pagination_class = ESDocumentPagination
|
||||
|
|
|
|||
|
|
@ -67,16 +67,23 @@ def get_default_locale():
|
|||
settings.FALLBACK_LOCALE
|
||||
|
||||
|
||||
def translate_field(self, field_name):
|
||||
def translate_field(self, field_name, toggle_field_name=None):
|
||||
def translate(self):
|
||||
field = getattr(self, field_name)
|
||||
toggler = getattr(self, toggle_field_name, None)
|
||||
if isinstance(field, dict):
|
||||
if toggler:
|
||||
field = {locale: v for locale, v in field.items() if toggler.get(locale) in [True, 'True', 'true']}
|
||||
value = field.get(to_locale(get_language()))
|
||||
# fallback
|
||||
if value is None:
|
||||
value = field.get(get_default_locale())
|
||||
if value is None:
|
||||
value = field.get(next(iter(field.keys()), None))
|
||||
try:
|
||||
value = next(iter(field.values()))
|
||||
except StopIteration:
|
||||
# field values are absent
|
||||
return None
|
||||
return value
|
||||
return None
|
||||
return translate
|
||||
|
|
@ -114,7 +121,7 @@ class TranslatedFieldsMixin:
|
|||
field_name = field.name
|
||||
if isinstance(field, TJSONField):
|
||||
setattr(cls, f'{field.name}_translated',
|
||||
property(translate_field(self, field_name)))
|
||||
property(translate_field(self, field_name, f'locale_to_{field_name}_is_active')))
|
||||
setattr(cls, f'{field_name}_indexing',
|
||||
property(index_field(self, field_name)))
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user