Merge branch 'develop' into feature/establishment-gallery
# Conflicts: # apps/product/serializers/common.py
This commit is contained in:
commit
dce951c4f9
17
apps/advertisement/migrations/0008_auto_20191116_1135.py
Normal file
17
apps/advertisement/migrations/0008_auto_20191116_1135.py
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Generated by Django 2.2.7 on 2019-11-16 11:35
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('advertisement', '0007_auto_20191115_0750'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='advertisement',
|
||||||
|
options={'verbose_name': 'Advertisement', 'verbose_name_plural': 'Advertisements'},
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -13,10 +13,50 @@ from utils.methods import get_user_ip
|
||||||
class CheckWhetherBookingAvailable(generics.GenericAPIView):
|
class CheckWhetherBookingAvailable(generics.GenericAPIView):
|
||||||
""" Checks which service to use if establishmend is managed by any """
|
""" Checks which service to use if establishmend is managed by any """
|
||||||
|
|
||||||
|
_VALID_GUESTONLINE_PERIODS = {'lunch', 'dinner', 'afternoon', 'breakfast'}
|
||||||
|
_GUESTONLINE_PERIODS_TO_PRIOR = {
|
||||||
|
'breakfast': 1,
|
||||||
|
'lunch': 2,
|
||||||
|
'afternoon': 3,
|
||||||
|
'dinner': 4,
|
||||||
|
}
|
||||||
|
|
||||||
permission_classes = (permissions.AllowAny,)
|
permission_classes = (permissions.AllowAny,)
|
||||||
serializer_class = CheckBookingSerializer
|
serializer_class = CheckBookingSerializer
|
||||||
pagination_class = None
|
pagination_class = None
|
||||||
|
|
||||||
|
def _fill_period_template(self, period_template, period_name):
|
||||||
|
period_template_copy = period_template.copy()
|
||||||
|
period_template_copy['period'] = period_name
|
||||||
|
return period_template_copy
|
||||||
|
|
||||||
|
def _preprocess_guestonline_response(self, response):
|
||||||
|
periods = response['periods']
|
||||||
|
periods_by_name = {period['period']: period for period in periods if 'period' in period}
|
||||||
|
if not periods_by_name:
|
||||||
|
raise ValueError('Empty guestonline response')
|
||||||
|
|
||||||
|
period_template = iter(periods_by_name.values()).__next__().copy()
|
||||||
|
period_template.pop('total_left_seats')
|
||||||
|
period_template['hours'] = []
|
||||||
|
period_template.pop('period')
|
||||||
|
|
||||||
|
processed_periods = [
|
||||||
|
periods_by_name[period_name]
|
||||||
|
if period_name in periods_by_name
|
||||||
|
else self._fill_period_template(period_template, period_name)
|
||||||
|
for period_name in CheckWhetherBookingAvailable._VALID_GUESTONLINE_PERIODS
|
||||||
|
]
|
||||||
|
|
||||||
|
unnamed_periods = filter(lambda period: 'period' not in period, periods)
|
||||||
|
for unnamed_period in unnamed_periods:
|
||||||
|
processed_periods.append(unnamed_period)
|
||||||
|
|
||||||
|
response['periods'] = sorted(processed_periods,
|
||||||
|
key=lambda x: self._GUESTONLINE_PERIODS_TO_PRIOR[x.get('period', 'lunch')])
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
is_booking_available = False
|
is_booking_available = False
|
||||||
establishment = get_object_or_404(Establishment, pk=kwargs['establishment_id'])
|
establishment = get_object_or_404(Establishment, pk=kwargs['establishment_id'])
|
||||||
|
|
@ -24,12 +64,12 @@ class CheckWhetherBookingAvailable(generics.GenericAPIView):
|
||||||
date = request.query_params.get('date')
|
date = request.query_params.get('date')
|
||||||
g_service = GuestonlineService()
|
g_service = GuestonlineService()
|
||||||
l_service = LastableService()
|
l_service = LastableService()
|
||||||
if (not establishment.lastable_id is None) and l_service \
|
if establishment.lastable_id is not None and l_service \
|
||||||
.check_whether_booking_available(establishment.lastable_id, date):
|
.check_whether_booking_available(establishment.lastable_id, date):
|
||||||
is_booking_available = True
|
is_booking_available = True
|
||||||
service = l_service
|
service = l_service
|
||||||
service.service_id = establishment.lastable_id
|
service.service_id = establishment.lastable_id
|
||||||
elif (not establishment.guestonline_id is None) and g_service \
|
elif establishment.guestonline_id is not None and g_service \
|
||||||
.check_whether_booking_available(establishment.guestonline_id,
|
.check_whether_booking_available(establishment.guestonline_id,
|
||||||
**g_service.get_certain_keys(request.query_params,
|
**g_service.get_certain_keys(request.query_params,
|
||||||
{'date', 'persons'})):
|
{'date', 'persons'})):
|
||||||
|
|
@ -41,7 +81,11 @@ class CheckWhetherBookingAvailable(generics.GenericAPIView):
|
||||||
'available': is_booking_available,
|
'available': is_booking_available,
|
||||||
'type': service.service if service else None,
|
'type': service.service if service else None,
|
||||||
}
|
}
|
||||||
response.update({'details': service.response} if service and service.response else {})
|
|
||||||
|
service_response = self._preprocess_guestonline_response(service.response) \
|
||||||
|
if establishment.guestonline_id is not None \
|
||||||
|
else service.response
|
||||||
|
response.update({'details': service_response} if service and service.response else {})
|
||||||
return Response(data=response, status=200)
|
return Response(data=response, status=200)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -97,8 +141,9 @@ class UpdatePendingBooking(generics.UpdateAPIView):
|
||||||
r = service.update_booking(service.get_certain_keys(data, {
|
r = service.update_booking(service.get_certain_keys(data, {
|
||||||
'email', 'phone', 'last_name', 'first_name', 'country_code', 'pending_booking_id', 'note',
|
'email', 'phone', 'last_name', 'first_name', 'country_code', 'pending_booking_id', 'note',
|
||||||
}, {
|
}, {
|
||||||
'email', 'phone', 'last_name', 'first_name', 'country_code', 'pending_booking_id',
|
'email', 'phone', 'last_name', 'first_name',
|
||||||
}))
|
'country_code', 'pending_booking_id',
|
||||||
|
}))
|
||||||
if isinstance(r, Response):
|
if isinstance(r, Response):
|
||||||
return r
|
return r
|
||||||
if data.get('newsletter'):
|
if data.get('newsletter'):
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
from rest_framework import generics
|
from rest_framework import generics
|
||||||
from rest_framework import permissions
|
from rest_framework import permissions
|
||||||
|
|
||||||
from collection import models
|
from collection import models
|
||||||
from utils.pagination import ProjectPageNumberPagination
|
|
||||||
from django.shortcuts import get_object_or_404
|
|
||||||
from establishment.serializers import EstablishmentBaseSerializer
|
|
||||||
from collection.serializers import common as serializers
|
from collection.serializers import common as serializers
|
||||||
|
from establishment.serializers import EstablishmentSimilarSerializer
|
||||||
|
from utils.pagination import ProjectPageNumberPagination
|
||||||
|
|
||||||
|
|
||||||
# Mixins
|
# Mixins
|
||||||
|
|
@ -53,7 +53,7 @@ class CollectionEstablishmentListView(CollectionListView):
|
||||||
"""Retrieve list of establishment for collection."""
|
"""Retrieve list of establishment for collection."""
|
||||||
lookup_field = 'slug'
|
lookup_field = 'slug'
|
||||||
pagination_class = ProjectPageNumberPagination
|
pagination_class = ProjectPageNumberPagination
|
||||||
serializer_class = EstablishmentBaseSerializer
|
serializer_class = EstablishmentSimilarSerializer
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ from rest_framework import serializers
|
||||||
from comment import models as comment_models
|
from comment import models as comment_models
|
||||||
from comment.serializers import common as comment_serializers
|
from comment.serializers import common as comment_serializers
|
||||||
from establishment import models
|
from establishment import models
|
||||||
from location.serializers import AddressBaseSerializer, CitySerializer, AddressDetailSerializer
|
from location.serializers import AddressBaseSerializer, CitySerializer, AddressDetailSerializer, CityShortSerializer
|
||||||
from main.serializers import AwardSerializer, CurrencySerializer
|
from main.serializers import AwardSerializer, CurrencySerializer
|
||||||
from tag.serializers import TagBaseSerializer
|
from tag.serializers import TagBaseSerializer
|
||||||
from timetable.serialziers import ScheduleRUDSerializer
|
from timetable.serialziers import ScheduleRUDSerializer
|
||||||
|
|
@ -18,6 +18,7 @@ from utils.serializers import ImageBaseSerializer
|
||||||
|
|
||||||
class ContactPhonesSerializer(serializers.ModelSerializer):
|
class ContactPhonesSerializer(serializers.ModelSerializer):
|
||||||
"""Contact phone serializer"""
|
"""Contact phone serializer"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.ContactPhone
|
model = models.ContactPhone
|
||||||
fields = [
|
fields = [
|
||||||
|
|
@ -27,6 +28,7 @@ class ContactPhonesSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
class ContactEmailsSerializer(serializers.ModelSerializer):
|
class ContactEmailsSerializer(serializers.ModelSerializer):
|
||||||
"""Contact email serializer"""
|
"""Contact email serializer"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.ContactEmail
|
model = models.ContactEmail
|
||||||
fields = [
|
fields = [
|
||||||
|
|
@ -36,6 +38,7 @@ class ContactEmailsSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
class SocialNetworkRelatedSerializers(serializers.ModelSerializer):
|
class SocialNetworkRelatedSerializers(serializers.ModelSerializer):
|
||||||
"""Social network serializers."""
|
"""Social network serializers."""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.SocialNetwork
|
model = models.SocialNetwork
|
||||||
fields = [
|
fields = [
|
||||||
|
|
@ -46,7 +49,6 @@ class SocialNetworkRelatedSerializers(serializers.ModelSerializer):
|
||||||
|
|
||||||
|
|
||||||
class PlateSerializer(ProjectModelSerializer):
|
class PlateSerializer(ProjectModelSerializer):
|
||||||
|
|
||||||
name_translated = TranslatedField()
|
name_translated = TranslatedField()
|
||||||
currency = CurrencySerializer(read_only=True)
|
currency = CurrencySerializer(read_only=True)
|
||||||
|
|
||||||
|
|
@ -192,6 +194,28 @@ class EstablishmentShortSerializer(serializers.ModelSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class EstablishmentProductShortSerializer(serializers.ModelSerializer):
|
||||||
|
"""SHORT Serializer for displaying info about an establishment on product page."""
|
||||||
|
establishment_type = EstablishmentTypeGeoSerializer()
|
||||||
|
establishment_subtypes = EstablishmentSubTypeBaseSerializer(many=True)
|
||||||
|
address = AddressBaseSerializer()
|
||||||
|
city = CityShortSerializer(source='address.city', allow_null=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""Meta class."""
|
||||||
|
model = models.Establishment
|
||||||
|
fields = [
|
||||||
|
'id',
|
||||||
|
'name',
|
||||||
|
'index_name',
|
||||||
|
'slug',
|
||||||
|
'city',
|
||||||
|
'establishment_type',
|
||||||
|
'establishment_subtypes',
|
||||||
|
'address',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentProductSerializer(EstablishmentShortSerializer):
|
class EstablishmentProductSerializer(EstablishmentShortSerializer):
|
||||||
"""Serializer for displaying info about an establishment on product page."""
|
"""Serializer for displaying info about an establishment on product page."""
|
||||||
|
|
||||||
|
|
@ -325,6 +349,12 @@ class EstablishmentDetailSerializer(EstablishmentBaseSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class EstablishmentSimilarSerializer(EstablishmentBaseSerializer):
|
||||||
|
"""Serializer for Establishment model."""
|
||||||
|
|
||||||
|
address = AddressDetailSerializer(read_only=True)
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentCommentCreateSerializer(comment_serializers.CommentSerializer):
|
class EstablishmentCommentCreateSerializer(comment_serializers.CommentSerializer):
|
||||||
"""Create comment serializer"""
|
"""Create comment serializer"""
|
||||||
mark = serializers.IntegerField()
|
mark = serializers.IntegerField()
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ class EstablishmentRecentReviewListView(EstablishmentListView):
|
||||||
class EstablishmentSimilarListView(EstablishmentListView):
|
class EstablishmentSimilarListView(EstablishmentListView):
|
||||||
"""Resource for getting a list of establishments."""
|
"""Resource for getting a list of establishments."""
|
||||||
|
|
||||||
serializer_class = serializers.EstablishmentBaseSerializer
|
serializer_class = serializers.EstablishmentSimilarSerializer
|
||||||
pagination_class = EstablishmentPortionPagination
|
pagination_class = EstablishmentPortionPagination
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,20 @@ class RegionSerializer(serializers.ModelSerializer):
|
||||||
'country_id'
|
'country_id'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
class CityShortSerializer(serializers.ModelSerializer):
|
||||||
|
"""Short city serializer"""
|
||||||
|
country = CountrySerializer(read_only=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""Meta class"""
|
||||||
|
model = models.City
|
||||||
|
fields = (
|
||||||
|
'id',
|
||||||
|
'name',
|
||||||
|
'code',
|
||||||
|
'country',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CitySerializer(serializers.ModelSerializer):
|
class CitySerializer(serializers.ModelSerializer):
|
||||||
"""City serializer."""
|
"""City serializer."""
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
"""Location app views."""
|
"""Location app views."""
|
||||||
from rest_framework import generics
|
from rest_framework import generics
|
||||||
from rest_framework import permissions
|
from rest_framework import permissions
|
||||||
|
from django.db.models.expressions import RawSQL
|
||||||
from location import models, serializers
|
from location import models, serializers
|
||||||
|
from utils.models import get_current_locale
|
||||||
|
|
||||||
|
|
||||||
# Mixins
|
# Mixins
|
||||||
|
|
@ -37,7 +38,9 @@ class CountryListView(CountryViewMixin, generics.ListAPIView):
|
||||||
"""List view for model Country."""
|
"""List view for model Country."""
|
||||||
|
|
||||||
pagination_class = None
|
pagination_class = None
|
||||||
|
def get_queryset(self):
|
||||||
|
qs = super().get_queryset().order_by(RawSQL("name->>%s", (get_current_locale(),)))
|
||||||
|
return qs
|
||||||
|
|
||||||
class CountryRetrieveView(CountryViewMixin, generics.RetrieveAPIView):
|
class CountryRetrieveView(CountryViewMixin, generics.RetrieveAPIView):
|
||||||
"""Retrieve view for model Country."""
|
"""Retrieve view for model Country."""
|
||||||
|
|
|
||||||
20
apps/notification/migrations/0003_auto_20191116_1248.py
Normal file
20
apps/notification/migrations/0003_auto_20191116_1248.py
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Generated by Django 2.2.7 on 2019-11-16 12:48
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('notification', '0002_subscriber_old_id'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='subscriber',
|
||||||
|
name='user',
|
||||||
|
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subscriber', to=settings.AUTH_USER_MODEL, verbose_name='User'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -74,7 +74,7 @@ class Subscriber(ProjectBaseMixin):
|
||||||
(USABLE, _('Usable')),
|
(USABLE, _('Usable')),
|
||||||
)
|
)
|
||||||
|
|
||||||
user = models.OneToOneField(
|
user = models.ForeignKey(
|
||||||
User,
|
User,
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True,
|
null=True,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
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,14 +23,14 @@ def transfer_newsletter_subscriber():
|
||||||
'email_address__ip',
|
'email_address__ip',
|
||||||
'email_address__country_code',
|
'email_address__country_code',
|
||||||
'email_address__locale',
|
'email_address__locale',
|
||||||
'created_at',
|
'updated_at',
|
||||||
)
|
)
|
||||||
|
|
||||||
# serialized_data = NewsletterSubscriberSerializer(data=list(queryset.values()), many=True)
|
serialized_data = NewsletterSubscriberSerializer(data=list(queryset), 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 = {
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,12 @@ class ProductQuerySet(models.QuerySet):
|
||||||
def with_extended_related(self):
|
def with_extended_related(self):
|
||||||
"""Returns qs with almost all related objects."""
|
"""Returns qs with almost all related objects."""
|
||||||
return self.with_base_related() \
|
return self.with_base_related() \
|
||||||
.prefetch_related('tags', 'standards', 'classifications', 'classifications__standard',
|
.prefetch_related('tags', 'tags__category', 'tags__category__country',
|
||||||
|
'standards', 'classifications', 'classifications__standard',
|
||||||
|
'establishment__address', 'establishment__establishment_type',
|
||||||
|
'establishment__address__city', 'establishment__address__city__country',
|
||||||
|
'establishment__establishment_subtypes', 'product_gallery',
|
||||||
|
'gallery', 'product_type', 'subtypes',
|
||||||
'classifications__classification_type', 'classifications__tags') \
|
'classifications__classification_type', 'classifications__tags') \
|
||||||
.select_related('wine_region', 'wine_sub_region')
|
.select_related('wine_region', 'wine_sub_region')
|
||||||
|
|
||||||
|
|
@ -247,15 +252,14 @@ class Product(GalleryModelMixin, TranslatedFieldsMixin, BaseAttributes):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def related_tags(self):
|
def related_tags(self):
|
||||||
return self.tags.exclude(
|
return self.tags.exclude(category__index_name__in=['sugar-content', 'wine-color', 'bottles-produced',
|
||||||
category__index_name__in=['sugar-content', 'wine-color', 'bottles-produced',
|
'serial-number', 'grape-variety']).prefetch_related('category')
|
||||||
'serial-number', 'grape-variety'])
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def display_name(self):
|
def display_name(self):
|
||||||
name = f'{self.name} ' \
|
name = f'{self.name} ' \
|
||||||
f'({self.vintage if self.vintage else "BSA"})'
|
f'({self.vintage if self.vintage else "BSA"})'
|
||||||
if self.establishment.name:
|
if self.establishment and self.establishment.name:
|
||||||
name = f'{self.establishment.name} - ' + name
|
name = f'{self.establishment.name} - ' + name
|
||||||
return name
|
return name
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ from rest_framework import serializers
|
||||||
|
|
||||||
from comment.models import Comment
|
from comment.models import Comment
|
||||||
from comment.serializers import CommentSerializer
|
from comment.serializers import CommentSerializer
|
||||||
from establishment.serializers import EstablishmentShortSerializer, EstablishmentProductSerializer
|
from establishment.serializers import EstablishmentShortSerializer, EstablishmentProductSerializer, EstablishmentProductShortSerializer
|
||||||
from gallery.models import Image
|
from gallery.models import Image
|
||||||
from product import models
|
from product import models
|
||||||
from review.serializers import ReviewShortSerializer
|
from review.serializers import ReviewShortSerializer
|
||||||
|
|
@ -12,13 +12,13 @@ from utils import exceptions as utils_exceptions
|
||||||
from utils.serializers import TranslatedField, FavoritesCreateSerializer, ImageBaseSerializer
|
from utils.serializers import TranslatedField, FavoritesCreateSerializer, ImageBaseSerializer
|
||||||
from main.serializers import AwardSerializer
|
from main.serializers import AwardSerializer
|
||||||
from location.serializers import WineRegionBaseSerializer, WineSubRegionBaseSerializer
|
from location.serializers import WineRegionBaseSerializer, WineSubRegionBaseSerializer
|
||||||
from tag.serializers import TagBaseSerializer, TagCategoryShortSerializer
|
from tag.serializers import TagBaseSerializer, TagCategoryProductSerializer
|
||||||
|
|
||||||
|
|
||||||
class ProductTagSerializer(TagBaseSerializer):
|
class ProductTagSerializer(TagBaseSerializer):
|
||||||
"""Serializer for model Tag."""
|
"""Serializer for model Tag."""
|
||||||
|
|
||||||
category = TagCategoryShortSerializer(read_only=True)
|
category = TagCategoryProductSerializer(read_only=True)
|
||||||
|
|
||||||
class Meta(TagBaseSerializer.Meta):
|
class Meta(TagBaseSerializer.Meta):
|
||||||
"""Meta class."""
|
"""Meta class."""
|
||||||
|
|
@ -83,21 +83,12 @@ class ProductStandardBaseSerializer(serializers.ModelSerializer):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ProductCropImageSerializer(serializers.Serializer):
|
|
||||||
"""Serializer for product image."""
|
|
||||||
|
|
||||||
|
|
||||||
class ProductImageSerializer(ImageBaseSerializer):
|
|
||||||
"""Serializer for product image."""
|
|
||||||
auto_crop_images = ProductCropImageSerializer(allow_null=True)
|
|
||||||
|
|
||||||
|
|
||||||
class ProductBaseSerializer(serializers.ModelSerializer):
|
class ProductBaseSerializer(serializers.ModelSerializer):
|
||||||
"""Product base serializer."""
|
"""Product base serializer."""
|
||||||
name = serializers.CharField(source='display_name', read_only=True)
|
name = serializers.CharField(source='display_name', read_only=True)
|
||||||
product_type = ProductTypeBaseSerializer(read_only=True)
|
product_type = ProductTypeBaseSerializer(read_only=True)
|
||||||
subtypes = ProductSubTypeBaseSerializer(many=True, read_only=True)
|
subtypes = ProductSubTypeBaseSerializer(many=True, read_only=True)
|
||||||
establishment_detail = EstablishmentShortSerializer(source='establishment', read_only=True)
|
establishment_detail = EstablishmentProductShortSerializer(source='establishment', read_only=True)
|
||||||
tags = ProductTagSerializer(source='related_tags', many=True, read_only=True)
|
tags = ProductTagSerializer(source='related_tags', many=True, read_only=True)
|
||||||
wine_region = WineRegionBaseSerializer(read_only=True)
|
wine_region = WineRegionBaseSerializer(read_only=True)
|
||||||
wine_colors = TagBaseSerializer(many=True, read_only=True)
|
wine_colors = TagBaseSerializer(many=True, read_only=True)
|
||||||
|
|
@ -128,6 +119,7 @@ class ProductBaseSerializer(serializers.ModelSerializer):
|
||||||
class ProductDetailSerializer(ProductBaseSerializer):
|
class ProductDetailSerializer(ProductBaseSerializer):
|
||||||
"""Product detail serializer."""
|
"""Product detail serializer."""
|
||||||
description_translated = TranslatedField()
|
description_translated = TranslatedField()
|
||||||
|
establishment_detail = EstablishmentShortSerializer(source='establishment', read_only=True)
|
||||||
review = ReviewShortSerializer(source='last_published_review', read_only=True)
|
review = ReviewShortSerializer(source='last_published_review', read_only=True)
|
||||||
awards = AwardSerializer(many=True, read_only=True)
|
awards = AwardSerializer(many=True, read_only=True)
|
||||||
classifications = ProductClassificationBaseSerializer(many=True, read_only=True)
|
classifications = ProductClassificationBaseSerializer(many=True, read_only=True)
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,10 @@ class ProductListView(ProductBaseView, generics.ListAPIView):
|
||||||
serializer_class = serializers.ProductBaseSerializer
|
serializer_class = serializers.ProductBaseSerializer
|
||||||
filter_class = filters.ProductFilterSet
|
filter_class = filters.ProductFilterSet
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
qs = super().get_queryset().with_extended_related()
|
||||||
|
return qs
|
||||||
|
|
||||||
|
|
||||||
class ProductDetailView(ProductBaseView, generics.RetrieveAPIView):
|
class ProductDetailView(ProductBaseView, generics.RetrieveAPIView):
|
||||||
"""Detail view fro model Product."""
|
"""Detail view fro model Product."""
|
||||||
|
|
|
||||||
|
|
@ -95,13 +95,15 @@ class ProductDocument(Document):
|
||||||
},
|
},
|
||||||
multi=True
|
multi=True
|
||||||
)
|
)
|
||||||
|
name = fields.TextField(attr='display_name', analyzer='english')
|
||||||
|
name_ru = fields.TextField(attr='display_name', analyzer='russian')
|
||||||
|
name_fr = fields.TextField(attr='display_name', analyzer='french')
|
||||||
|
|
||||||
class Django:
|
class Django:
|
||||||
model = models.Product
|
model = models.Product
|
||||||
fields = (
|
fields = (
|
||||||
'id',
|
'id',
|
||||||
'category',
|
'category',
|
||||||
'name',
|
|
||||||
'available',
|
'available',
|
||||||
'public_mark',
|
'public_mark',
|
||||||
'slug',
|
'slug',
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,8 @@ class ProductSubtypeDocumentSerializer(serializers.Serializer):
|
||||||
id = serializers.IntegerField()
|
id = serializers.IntegerField()
|
||||||
name_translated = serializers.SerializerMethodField()
|
name_translated = serializers.SerializerMethodField()
|
||||||
|
|
||||||
get_name_translated = lambda obj: get_translated_value(obj.name)
|
def get_name_translated(self, obj):
|
||||||
|
return get_translated_value(obj.name)
|
||||||
|
|
||||||
|
|
||||||
class WineRegionCountryDocumentSerialzer(serializers.Serializer):
|
class WineRegionCountryDocumentSerialzer(serializers.Serializer):
|
||||||
|
|
@ -64,6 +65,9 @@ class WineRegionDocumentSerializer(serializers.Serializer):
|
||||||
name = serializers.CharField()
|
name = serializers.CharField()
|
||||||
country = WineRegionCountryDocumentSerialzer(allow_null=True)
|
country = WineRegionCountryDocumentSerialzer(allow_null=True)
|
||||||
|
|
||||||
|
def get_attribute(self, instance):
|
||||||
|
return instance.wine_region if instance and instance.wine_region else None
|
||||||
|
|
||||||
|
|
||||||
class WineColorDocumentSerializer(serializers.Serializer):
|
class WineColorDocumentSerializer(serializers.Serializer):
|
||||||
"""Wine color ES document serializer,"""
|
"""Wine color ES document serializer,"""
|
||||||
|
|
@ -79,6 +83,18 @@ class WineColorDocumentSerializer(serializers.Serializer):
|
||||||
return get_translated_value(obj.label)
|
return get_translated_value(obj.label)
|
||||||
|
|
||||||
|
|
||||||
|
class ProductTypeDocumentSerializer(serializers.Serializer):
|
||||||
|
"""Product type ES document serializer."""
|
||||||
|
|
||||||
|
id = serializers.IntegerField()
|
||||||
|
index_name = serializers.CharField()
|
||||||
|
name_translated = serializers.SerializerMethodField()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_name_translated(obj):
|
||||||
|
return get_translated_value(obj.name)
|
||||||
|
|
||||||
|
|
||||||
class ProductEstablishmentDocumentSerializer(serializers.Serializer):
|
class ProductEstablishmentDocumentSerializer(serializers.Serializer):
|
||||||
"""Related to Product Establishment ES document serializer."""
|
"""Related to Product Establishment ES document serializer."""
|
||||||
|
|
||||||
|
|
@ -199,16 +215,12 @@ class ProductDocumentSerializer(DocumentSerializer):
|
||||||
"""Product document serializer"""
|
"""Product document serializer"""
|
||||||
|
|
||||||
tags = TagsDocumentSerializer(many=True)
|
tags = TagsDocumentSerializer(many=True)
|
||||||
subtypes = ProductSubtypeDocumentSerializer(many=True)
|
subtypes = ProductSubtypeDocumentSerializer(many=True, allow_null=True)
|
||||||
wine_region = WineRegionDocumentSerializer(allow_null=True)
|
wine_region = WineRegionDocumentSerializer(allow_null=True)
|
||||||
wine_colors = WineColorDocumentSerializer(many=True)
|
wine_colors = WineColorDocumentSerializer(many=True)
|
||||||
product_type = serializers.SerializerMethodField()
|
product_type = ProductTypeDocumentSerializer(allow_null=True)
|
||||||
establishment_detail = ProductEstablishmentDocumentSerializer(source='establishment', allow_null=True)
|
establishment_detail = ProductEstablishmentDocumentSerializer(source='establishment', allow_null=True)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_product_type(obj):
|
|
||||||
return get_translated_value(obj.product_type.name if obj.product_type else {})
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""Meta class."""
|
"""Meta class."""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,8 +91,6 @@ class EstablishmentDocumentViewSet(BaseDocumentViewSet):
|
||||||
'boost': 4},
|
'boost': 4},
|
||||||
'transliterated_name': {'fuzziness': 'auto:2,5',
|
'transliterated_name': {'fuzziness': 'auto:2,5',
|
||||||
'boost': 3},
|
'boost': 3},
|
||||||
'index_name': {'fuzziness': 'auto:2,5',
|
|
||||||
'boost': 2},
|
|
||||||
'description': {'fuzziness': 'auto:2,5'},
|
'description': {'fuzziness': 'auto:2,5'},
|
||||||
}
|
}
|
||||||
translated_search_fields = (
|
translated_search_fields = (
|
||||||
|
|
@ -199,7 +197,7 @@ class ProductDocumentViewSet(BaseDocumentViewSet):
|
||||||
"""Product document ViewSet."""
|
"""Product document ViewSet."""
|
||||||
|
|
||||||
document = ProductDocument
|
document = ProductDocument
|
||||||
lookup_field = 'slug'
|
# lookup_field = 'slug'
|
||||||
pagination_class = ProjectMobilePagination
|
pagination_class = ProjectMobilePagination
|
||||||
permission_classes = (permissions.AllowAny,)
|
permission_classes = (permissions.AllowAny,)
|
||||||
serializer_class = serializers.ProductDocumentSerializer
|
serializer_class = serializers.ProductDocumentSerializer
|
||||||
|
|
@ -212,19 +210,22 @@ class ProductDocumentViewSet(BaseDocumentViewSet):
|
||||||
filter_backends = [
|
filter_backends = [
|
||||||
FilteringFilterBackend,
|
FilteringFilterBackend,
|
||||||
filters.CustomSearchFilterBackend,
|
filters.CustomSearchFilterBackend,
|
||||||
GeoSpatialFilteringFilterBackend,
|
# GeoSpatialFilteringFilterBackend,
|
||||||
DefaultOrderingFilterBackend,
|
# DefaultOrderingFilterBackend,
|
||||||
]
|
]
|
||||||
|
|
||||||
search_fields = {
|
search_fields = {
|
||||||
'name': {'fuzziness': 'auto:2,5',
|
'name': {'fuzziness': 'auto:2,5',
|
||||||
'boost': 4},
|
'boost': 8},
|
||||||
|
'name_ru': {'fuzziness': 'auto:2,5',
|
||||||
|
'boost': 6},
|
||||||
|
'name_fr': {'fuzziness': 'auto:2,5',
|
||||||
|
'boost': 7},
|
||||||
'transliterated_name': {'fuzziness': 'auto:2,5',
|
'transliterated_name': {'fuzziness': 'auto:2,5',
|
||||||
'boost': 3},
|
'boost': 3},
|
||||||
'index_name': {'fuzziness': 'auto:2,5',
|
|
||||||
'boost': 2},
|
|
||||||
'description': {'fuzziness': 'auto:2,5'},
|
'description': {'fuzziness': 'auto:2,5'},
|
||||||
}
|
}
|
||||||
|
|
||||||
translated_search_fields = (
|
translated_search_fields = (
|
||||||
'description',
|
'description',
|
||||||
)
|
)
|
||||||
|
|
@ -248,7 +249,7 @@ class ProductDocumentViewSet(BaseDocumentViewSet):
|
||||||
'for_establishment': {
|
'for_establishment': {
|
||||||
'field': 'establishment.slug',
|
'field': 'establishment.slug',
|
||||||
},
|
},
|
||||||
'type': {
|
'product_type': {
|
||||||
'field': 'product_type.index_name',
|
'field': 'product_type.index_name',
|
||||||
},
|
},
|
||||||
'subtype': {
|
'subtype': {
|
||||||
|
|
@ -259,5 +260,5 @@ class ProductDocumentViewSet(BaseDocumentViewSet):
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
geo_spatial_filter_fields = {
|
# geo_spatial_filter_fields = {
|
||||||
}
|
# }
|
||||||
|
|
@ -31,13 +31,18 @@ class TagCategoryFilterSet(TagsBaseFilterSet):
|
||||||
"""TagCategory filterset."""
|
"""TagCategory filterset."""
|
||||||
|
|
||||||
establishment_type = filters.CharFilter(method='by_establishment_type')
|
establishment_type = filters.CharFilter(method='by_establishment_type')
|
||||||
|
product_type = filters.CharFilter(method='by_product_type')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""Meta class."""
|
"""Meta class."""
|
||||||
|
|
||||||
model = models.TagCategory
|
model = models.TagCategory
|
||||||
fields = ('type',
|
fields = ('type',
|
||||||
'establishment_type', )
|
'establishment_type',
|
||||||
|
'product_type', )
|
||||||
|
|
||||||
|
def by_product_type(self, queryset, name, value):
|
||||||
|
return queryset.by_product_type(value)
|
||||||
|
|
||||||
# todo: filter by establishment type
|
# todo: filter by establishment type
|
||||||
def by_establishment_type(self, queryset, name, value):
|
def by_establishment_type(self, queryset, name, value):
|
||||||
|
|
|
||||||
|
|
@ -3,87 +3,116 @@ from django.core.management.base import BaseCommand
|
||||||
from establishment.models import Establishment, EstablishmentType
|
from establishment.models import Establishment, EstablishmentType
|
||||||
from transfer import models as legacy
|
from transfer import models as legacy
|
||||||
from tag.models import Tag, TagCategory
|
from tag.models import Tag, TagCategory
|
||||||
|
from tqdm import tqdm
|
||||||
|
from django.db import connections
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
|
|
||||||
|
def namedtuplefetchall(cursor):
|
||||||
|
"Return all rows from a cursor as a namedtuple"
|
||||||
|
desc = cursor.description
|
||||||
|
nt_result = namedtuple('Result', [col[0] for col in desc])
|
||||||
|
return [nt_result(*row) for row in cursor.fetchall()]
|
||||||
|
|
||||||
|
|
||||||
|
def metadata_category_sql():
|
||||||
|
with connections['legacy'].cursor() as cursor:
|
||||||
|
cursor.execute(
|
||||||
|
'''SELECT
|
||||||
|
`key`,
|
||||||
|
establishments.type,
|
||||||
|
key_value_metadata.`value_type`,
|
||||||
|
public,
|
||||||
|
key_value_metadata.id as 'old_id'
|
||||||
|
FROM metadata
|
||||||
|
LEFT JOIN establishments
|
||||||
|
ON metadata.establishment_id=establishments.id
|
||||||
|
LEFT JOIN key_value_metadata
|
||||||
|
ON metadata.key=key_value_metadata.key_name
|
||||||
|
GROUP BY
|
||||||
|
establishments.type,
|
||||||
|
`key`,
|
||||||
|
key_value_metadata.`value_type`,
|
||||||
|
public, old_id;'''
|
||||||
|
)
|
||||||
|
return namedtuplefetchall(cursor)
|
||||||
|
|
||||||
|
|
||||||
|
def metadata_tags_sql():
|
||||||
|
with connections['legacy'].cursor() as cursor:
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
SELECT
|
||||||
|
value,
|
||||||
|
`key` as category,
|
||||||
|
establishment_id
|
||||||
|
FROM metadata
|
||||||
|
WHERE establishment_id is not null"""
|
||||||
|
)
|
||||||
|
return namedtuplefetchall(cursor)
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = 'Add tags values from old db to new db'
|
help = 'Add tags values from old db to new db'
|
||||||
|
|
||||||
|
def get_type(self, meta):
|
||||||
|
meta_type = meta.value_type
|
||||||
|
if not meta.value_type:
|
||||||
|
if meta.key == 'wineyard_visits':
|
||||||
|
meta_type = 'list'
|
||||||
|
elif meta.key in ['private_room', 'outside_sits']:
|
||||||
|
meta_type = 'bool'
|
||||||
|
return meta_type
|
||||||
|
|
||||||
|
def get_label(self, text):
|
||||||
|
sp = text.split('_')
|
||||||
|
label = ' '.join([sp[0].capitalize()] + sp[1:])
|
||||||
|
return label
|
||||||
|
|
||||||
def handle(self, *args, **kwargs):
|
def handle(self, *args, **kwargs):
|
||||||
|
|
||||||
existing_establishment = Establishment.objects.filter(
|
existing_establishment = Establishment.objects.filter(
|
||||||
old_id__isnull=False, tags__isnull=True
|
old_id__isnull=False
|
||||||
)
|
)
|
||||||
ESTABLISHMENT = 1
|
|
||||||
SHOP = 2
|
|
||||||
RESTAURANT = 3
|
|
||||||
WINEYARD = 4
|
|
||||||
|
|
||||||
MAPPER = {
|
MAPPER = {
|
||||||
RESTAURANT: EstablishmentType.RESTAURANT,
|
'Restaurant': EstablishmentType.RESTAURANT,
|
||||||
WINEYARD: EstablishmentType.PRODUCER,
|
'Wineyard': EstablishmentType.PRODUCER,
|
||||||
SHOP: EstablishmentType.ARTISAN
|
'Shop': EstablishmentType.ARTISAN
|
||||||
}
|
}
|
||||||
|
# remove old black category
|
||||||
|
for establishment_tag in tqdm(EstablishmentType.objects.all()):
|
||||||
|
establishment_tag.tag_categories.remove(*list(
|
||||||
|
establishment_tag.tag_categories.exclude(
|
||||||
|
tags__establishments__isnull=False).distinct()))
|
||||||
|
|
||||||
mapper_values_meta = legacy.KeyValueMetadatumKeyValueMetadatumEstablishments.objects.all()
|
# created Tag Category
|
||||||
for key, value in MAPPER.items():
|
for meta in tqdm(metadata_category_sql()):
|
||||||
values_meta_id_list = mapper_values_meta.filter(
|
category, _ = TagCategory.objects.update_or_create(
|
||||||
key_value_metadatum_establishment_id=key
|
index_name=meta.key,
|
||||||
).values_list('key_value_metadatum_id')
|
defaults={
|
||||||
|
"public": True if meta.public == 1 else False,
|
||||||
|
"value_type": self.get_type(meta),
|
||||||
|
"label": {"en-GB": self.get_label(meta.key)}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
est_type, _ = EstablishmentType.objects.get_or_create(index_name=value)
|
# add to EstablishmentType
|
||||||
|
est_type = EstablishmentType.objects.get(index_name=MAPPER[meta.type])
|
||||||
|
if category not in est_type.tag_categories.all():
|
||||||
|
est_type.tag_categories.add(category)
|
||||||
|
|
||||||
key_value_metadata = legacy.KeyValueMetadata.objects.filter(
|
count = 0
|
||||||
id__in=values_meta_id_list)
|
for meta_tag in tqdm(metadata_tags_sql()):
|
||||||
|
|
||||||
# create TagCategory
|
tag, _ = Tag.objects.update_or_create(
|
||||||
for key_value in key_value_metadata:
|
category=TagCategory.objects.get(index_name=meta_tag.category),
|
||||||
tag_category, created = TagCategory.objects.get_or_create(
|
value=meta_tag.value,
|
||||||
index_name=key_value.key_name,
|
defaults={
|
||||||
)
|
"label": {"en-GB": self.get_label(meta_tag.value)}
|
||||||
|
}
|
||||||
if created:
|
)
|
||||||
tag_category.label = {
|
establishment = existing_establishment.filter(old_id=meta_tag.establishment_id).first()
|
||||||
'en-GB': key_value.key_name,
|
if establishment:
|
||||||
'fr-FR': key_value.key_name,
|
if tag not in establishment.tags.all():
|
||||||
'ru-RU': key_value.key_name,
|
establishment.tags.add(tag)
|
||||||
}
|
count += 1
|
||||||
tag_category.value_type = key_value.value_type
|
self.stdout.write(self.style.WARNING(f'Created {count} tags to Establishment'))
|
||||||
tag_category.save()
|
|
||||||
est_type.tag_categories.add(
|
|
||||||
tag_category
|
|
||||||
)
|
|
||||||
|
|
||||||
# create Tag
|
|
||||||
for tag in key_value.metadata_set.filter(
|
|
||||||
establishment__id__in=list(
|
|
||||||
existing_establishment.values_list('old_id', flat=True)
|
|
||||||
)):
|
|
||||||
|
|
||||||
new_tag, created = Tag.objects.get_or_create(
|
|
||||||
value=tag.value,
|
|
||||||
category=tag_category,
|
|
||||||
)
|
|
||||||
if created:
|
|
||||||
|
|
||||||
sp = tag.value.split('_')
|
|
||||||
value = ' '.join([sp[0].capitalize()] + sp[1:])
|
|
||||||
|
|
||||||
trans = {
|
|
||||||
'en-GB': value,
|
|
||||||
'fr-FR': value,
|
|
||||||
'ru-RU': value,
|
|
||||||
}
|
|
||||||
|
|
||||||
aliases = legacy.MetadatumAliases.objects.filter(value=tag.value)
|
|
||||||
|
|
||||||
for alias in aliases:
|
|
||||||
trans[alias.locale] = alias.meta_alias
|
|
||||||
|
|
||||||
new_tag.label = trans
|
|
||||||
new_tag.save()
|
|
||||||
|
|
||||||
est = existing_establishment.filter(
|
|
||||||
old_id=tag.establishment_id).first()
|
|
||||||
if est:
|
|
||||||
est.tags.add(new_tag)
|
|
||||||
est.save()
|
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,18 @@
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
from establishment.models import Establishment, EstablishmentType
|
from tag.models import Tag
|
||||||
from transfer import models as legacy
|
from transfer import models as legacy
|
||||||
from tag.models import Tag, TagCategory
|
from tqdm import tqdm
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = 'Add tags translation from old db to new db'
|
help = 'Add tags translation from old db to new db'
|
||||||
|
|
||||||
def handle(self, *args, **kwargs):
|
@staticmethod
|
||||||
translation = legacy.MetadatumAliases.objects.all()
|
def humanisation_tag(self):
|
||||||
# Humanisation for default values
|
"""Humanisation for default values."""
|
||||||
|
|
||||||
tags = Tag.objects.all()
|
tags = Tag.objects.all()
|
||||||
for tag in tags:
|
for tag in tqdm(tags):
|
||||||
value = tag.label
|
value = tag.label
|
||||||
for k, v in value.items():
|
for k, v in value.items():
|
||||||
if isinstance(v, str) and '_' in v:
|
if isinstance(v, str) and '_' in v:
|
||||||
|
|
@ -22,10 +21,14 @@ class Command(BaseCommand):
|
||||||
tag.label[k] = v
|
tag.label[k] = v
|
||||||
tag.save()
|
tag.save()
|
||||||
|
|
||||||
for trans in translation:
|
def handle(self, *args, **kwargs):
|
||||||
|
"""Translation for existed tags."""
|
||||||
|
translation = legacy.MetadatumAliases.objects.all()
|
||||||
|
# self.humanisation_tag()
|
||||||
|
for trans in tqdm(translation):
|
||||||
tag = Tag.objects.filter(value=trans.value).first()
|
tag = Tag.objects.filter(value=trans.value).first()
|
||||||
if tag:
|
if tag:
|
||||||
tag.label.update(
|
tag.label.update(
|
||||||
{trans.locale: trans.meta_alias}
|
{trans.locale: trans.meta_alias}
|
||||||
)
|
)
|
||||||
tag.save()
|
tag.save()
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ class Tag(TranslatedFieldsMixin, models.Model):
|
||||||
chosen_tag_settings = models.ManyToManyField(Country, through='ChosenTagSettings')
|
chosen_tag_settings = models.ManyToManyField(Country, through='ChosenTagSettings')
|
||||||
priority = models.PositiveIntegerField(null=True, default=0)
|
priority = models.PositiveIntegerField(null=True, default=0)
|
||||||
|
|
||||||
|
# It does not make sense since in the old base another structure with duplicates
|
||||||
old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None)
|
old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None)
|
||||||
|
|
||||||
old_id_meta_product = models.PositiveIntegerField(_('old id metadata product'),
|
old_id_meta_product = models.PositiveIntegerField(_('old id metadata product'),
|
||||||
|
|
@ -100,6 +101,10 @@ class TagCategoryQuerySet(models.QuerySet):
|
||||||
"""Filter by establishment type index name."""
|
"""Filter by establishment type index name."""
|
||||||
return self.filter(establishment_types__index_name=index_name)
|
return self.filter(establishment_types__index_name=index_name)
|
||||||
|
|
||||||
|
def by_product_type(self, index_name):
|
||||||
|
"""Filter by product type index name."""
|
||||||
|
return self.filter(product_types__index_name=index_name)
|
||||||
|
|
||||||
def with_tags(self, switcher=True):
|
def with_tags(self, switcher=True):
|
||||||
"""Filter by existing tags."""
|
"""Filter by existing tags."""
|
||||||
return self.exclude(tags__isnull=switcher)
|
return self.exclude(tags__isnull=switcher)
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,21 @@ class TagBackOfficeSerializer(TagBaseSerializer):
|
||||||
'category'
|
'category'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class TagCategoryProductSerializer(serializers.ModelSerializer):
|
||||||
|
"""SHORT Serializer for TagCategory"""
|
||||||
|
|
||||||
|
label_translated = TranslatedField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""Meta class."""
|
||||||
|
|
||||||
|
model = models.TagCategory
|
||||||
|
fields = (
|
||||||
|
'id',
|
||||||
|
'label_translated',
|
||||||
|
'index_name',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TagCategoryBaseSerializer(serializers.ModelSerializer):
|
class TagCategoryBaseSerializer(serializers.ModelSerializer):
|
||||||
"""Serializer for model TagCategory."""
|
"""Serializer for model TagCategory."""
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@ class AdvertisementSerializer(serializers.ModelSerializer):
|
||||||
href = serializers.CharField()
|
href = serializers.CharField()
|
||||||
site_id = serializers.PrimaryKeyRelatedField(
|
site_id = serializers.PrimaryKeyRelatedField(
|
||||||
queryset=Sites.objects.all())
|
queryset=Sites.objects.all())
|
||||||
start_at = serializers.DateTimeField(allow_null=True)
|
|
||||||
expire_at = serializers.DateTimeField(allow_null=True)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""Meta class."""
|
"""Meta class."""
|
||||||
|
|
@ -24,29 +22,27 @@ class AdvertisementSerializer(serializers.ModelSerializer):
|
||||||
'id',
|
'id',
|
||||||
'href',
|
'href',
|
||||||
'site_id',
|
'site_id',
|
||||||
'start_at',
|
|
||||||
'expire_at',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
def validate(self, data):
|
def validate(self, data):
|
||||||
data.update({
|
data.update({
|
||||||
'old_id': data.pop('id'),
|
'old_id': data.pop('id'),
|
||||||
'url': data.pop('href'),
|
'url': data.pop('href'),
|
||||||
'site': self.get_site(data.pop('site_id')),
|
'site_settings': self.get_site_settings(data.pop('site_id')),
|
||||||
'start': data.pop('start_at', None),
|
|
||||||
'end': data.pop('expire_at', None),
|
|
||||||
})
|
})
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
site = validated_data.pop('site')
|
site = validated_data.pop('site_settings')
|
||||||
obj, _ = self.Meta.model.objects.get_or_create(validated_data)
|
url = validated_data.get('url')
|
||||||
|
|
||||||
|
obj, _ = self.Meta.model.objects.get_or_create(url=url, defaults=validated_data)
|
||||||
|
|
||||||
if site and site not in obj.sites.all():
|
if site and site not in obj.sites.all():
|
||||||
obj.sites.add(site)
|
obj.sites.add(site)
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def get_site(self, subdomain):
|
def get_site_settings(self, subdomain):
|
||||||
subdomain = subdomain.country_code_2 if isinstance(subdomain, Sites) else subdomain
|
subdomain = subdomain.country_code_2 if isinstance(subdomain, Sites) else subdomain
|
||||||
qs = SiteSettings.objects.filter(subdomain=subdomain)
|
qs = SiteSettings.objects.filter(subdomain=subdomain)
|
||||||
if qs.exists():
|
if qs.exists():
|
||||||
|
|
@ -89,5 +85,5 @@ class AdvertisementImageSerializer(AdvertisementSerializer):
|
||||||
image_url = validated_data.get('image_url')
|
image_url = validated_data.get('image_url')
|
||||||
|
|
||||||
if advertisement and image_url:
|
if advertisement and image_url:
|
||||||
Page.objects.get_or_create(advertisement=advertisement, image_url=image_url, source=Page.MOBILE)
|
self.Meta.model.objects.get_or_create(source=Page.MOBILE, **validated_data)
|
||||||
Page.objects.get_or_create(advertisement=advertisement, image_url=image_url, source=Page.WEB)
|
self.Meta.model.objects.get_or_create(source=Page.WEB, **validated_data)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
from django.db import IntegrityError
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from account.models import User
|
from account.models import User
|
||||||
|
|
@ -41,10 +42,10 @@ class NewsletterSubscriberSerializer(serializers.Serializer):
|
||||||
id = serializers.IntegerField()
|
id = serializers.IntegerField()
|
||||||
email_address__email = serializers.CharField()
|
email_address__email = serializers.CharField()
|
||||||
email_address__account_id = serializers.IntegerField(allow_null=True)
|
email_address__account_id = serializers.IntegerField(allow_null=True)
|
||||||
email_address__ip = serializers.CharField(allow_null=True)
|
email_address__ip = serializers.CharField(allow_null=True, allow_blank=True)
|
||||||
email_address__country_code = serializers.CharField(allow_null=True)
|
email_address__country_code = serializers.CharField(allow_null=True, allow_blank=True)
|
||||||
email_address__locale = serializers.CharField(allow_null=True)
|
email_address__locale = serializers.CharField(allow_null=True, allow_blank=True)
|
||||||
created_at = serializers.DateTimeField(format='%m-%d-%Y %H:%M:%S')
|
updated_at = serializers.DateTimeField(format='%m-%d-%Y %H:%M:%S')
|
||||||
|
|
||||||
def validate(self, data):
|
def validate(self, data):
|
||||||
data.update({
|
data.update({
|
||||||
|
|
@ -53,18 +54,28 @@ class NewsletterSubscriberSerializer(serializers.Serializer):
|
||||||
'ip_address': data.pop('email_address__ip'),
|
'ip_address': data.pop('email_address__ip'),
|
||||||
'country_code': data.pop('email_address__country_code'),
|
'country_code': data.pop('email_address__country_code'),
|
||||||
'locale': data.pop('email_address__locale'),
|
'locale': data.pop('email_address__locale'),
|
||||||
'created': data.pop('created_at'),
|
'created': data.pop('updated_at'),
|
||||||
'user_id': self.get_user(data),
|
'user_id': self.get_user(data),
|
||||||
})
|
})
|
||||||
data.pop('email_address__account_id')
|
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(
|
try:
|
||||||
# old_id=validated_data['old_id'],
|
obj = Subscriber.objects.get(email=validated_data['email'])
|
||||||
# defaults=validated_data,
|
except Subscriber.DoesNotExist:
|
||||||
# )
|
obj = Subscriber.objects.create(**validated_data)
|
||||||
# return obj
|
else:
|
||||||
|
current_data = obj.created
|
||||||
|
if validated_data['created'] > current_data:
|
||||||
|
obj.ip_address = validated_data['ip_address']
|
||||||
|
obj.locale = validated_data['locale']
|
||||||
|
obj.country_code = validated_data['country_code']
|
||||||
|
obj.old_id = validated_data['old_id']
|
||||||
|
obj.created = validated_data['created']
|
||||||
|
obj.user_id = validated_data['user_id']
|
||||||
|
obj.save()
|
||||||
|
return obj
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_user(data):
|
def get_user(data):
|
||||||
|
|
@ -73,6 +84,6 @@ class NewsletterSubscriberSerializer(serializers.Serializer):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
user = User.objects.filter(old_id=data['email_address__account_id']).first()
|
user = User.objects.filter(old_id=data['email_address__account_id']).first()
|
||||||
if not user:
|
if user:
|
||||||
raise ValueError(f"User account not found with old_id {data['email_address__account_id']}")
|
return user.id
|
||||||
return user.id
|
return None
|
||||||
|
|
|
||||||
|
|
@ -80,11 +80,11 @@ LOGGING = {
|
||||||
'py.warnings': {
|
'py.warnings': {
|
||||||
'handlers': ['console'],
|
'handlers': ['console'],
|
||||||
},
|
},
|
||||||
'django.db.backends': {
|
# 'django.db.backends': {
|
||||||
'handlers': ['console', ],
|
# 'handlers': ['console', ],
|
||||||
'level': 'DEBUG',
|
# 'level': 'DEBUG',
|
||||||
'propagate': False,
|
# 'propagate': False,
|
||||||
},
|
# },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user