merge with debelop

This commit is contained in:
Dmitriy Kuzmenko 2019-12-13 15:47:05 +03:00
commit 6e72c7c0e4
15 changed files with 275 additions and 80 deletions

View File

@ -213,7 +213,13 @@ class EstablishmentQuerySet(models.QuerySet):
)) ))
def similar_base(self, establishment): def similar_base(self, establishment):
"""
Return filtered QuerySet by base filters.
Filters including:
1 Filter by type (and subtype) establishment.
2 Filter by published Review.
3 With annotated distance.
"""
filters = { filters = {
'reviews__status': Review.READY, 'reviews__status': Review.READY,
'establishment_type': establishment.establishment_type, 'establishment_type': establishment.establishment_type,
@ -224,27 +230,64 @@ class EstablishmentQuerySet(models.QuerySet):
.filter(**filters) \ .filter(**filters) \
.annotate_distance(point=establishment.location) .annotate_distance(point=establishment.location)
def similar_base_subquery(self, establishment, filters: dict) -> Subquery:
"""
Return filtered Subquery object by filters.
Filters including:
1 Filter by transmitted filters.
2 With ordering by distance.
"""
return Subquery(
self.similar_base(establishment)
.filter(**filters)
.order_by('distance')[:settings.LIMITING_QUERY_OBJECTS]
.values('id')
)
def similar_restaurants(self, slug): def similar_restaurants(self, slug):
""" """
Return QuerySet with objects that similar to Restaurant. Return QuerySet with objects that similar to Restaurant.
:param restaurant_slug: str Establishment slug :param slug: str restaurant slug
""" """
restaurant_qs = self.filter(slug=slug, restaurant_qs = self.filter(slug=slug)
public_mark__isnull=False)
if restaurant_qs.exists(): if restaurant_qs.exists():
establishment = restaurant_qs.first() restaurant = restaurant_qs.first()
subquery_filter_by_distance = Subquery( ids_by_subquery = self.similar_base_subquery(
self.similar_base(establishment) establishment=restaurant,
.filter(public_mark__gte=10, filters={
establishment_gallery__is_main=True) 'public_mark__gte': 10,
.order_by('distance')[:settings.LIMITING_QUERY_OBJECTS] 'establishment_gallery__is_main': True,
.values('id') }
) )
return self.filter(id__in=subquery_filter_by_distance) \ return self.filter(id__in=ids_by_subquery) \
.annotate_intermediate_public_mark() \ .annotate_intermediate_public_mark() \
.annotate_mark_similarity(mark=establishment.public_mark) \ .annotate_mark_similarity(mark=restaurant.public_mark) \
.order_by('mark_similarity') \ .order_by('mark_similarity') \
.distinct('mark_similarity', 'id') .distinct('mark_similarity', 'id')
else:
return self.none()
def similar_artisans(self, slug):
"""
Return QuerySet with objects that similar to Artisan.
:param slug: str artisan slug
"""
artisan_qs = self.filter(slug=slug)
if artisan_qs.exists():
artisan = artisan_qs.first()
ids_by_subquery = self.similar_base_subquery(
establishment=artisan,
filters={
'public_mark__gte': 10,
}
)
return self.filter(id__in=ids_by_subquery) \
.annotate_intermediate_public_mark() \
.annotate_mark_similarity(mark=artisan.public_mark) \
.order_by('mark_similarity') \
.distinct('mark_similarity', 'id')
else:
return self.none()
def by_wine_region(self, wine_region): def by_wine_region(self, wine_region):
""" """

View File

@ -21,6 +21,8 @@ urlpatterns = [
path('slug/<slug:slug>/similar/', views.RestaurantSimilarListView.as_view(), path('slug/<slug:slug>/similar/', views.RestaurantSimilarListView.as_view(),
name='similar-restaurants'), name='similar-restaurants'),
path('slug/<slug:slug>/similar/wineries/', views.WinerySimilarListView.as_view(), path('slug/<slug:slug>/similar/wineries/', views.WinerySimilarListView.as_view(),
name='similar-restaurants'), name='similar-wineries'),
path('slug/<slug:slug>/similar/artisans/', views.ArtisanSimilarListView.as_view(),
name='similar-artisans'),
] ]

View File

@ -1,15 +1,17 @@
"""Establishment app views.""" """Establishment app views."""
from django.http import Http404, HttpResponse from django.http import Http404, HttpResponse
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from rest_framework import generics, permissions from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import status from rest_framework import generics, permissions, status
from account.models import User from account.models import User
from establishment import filters, models, serializers from establishment import filters, models, serializers
from timetable.models import Timetable
from timetable.serialziers import ScheduleRUDSerializer, ScheduleCreateSerializer from timetable.serialziers import ScheduleRUDSerializer, ScheduleCreateSerializer
from utils.permissions import IsCountryAdmin, IsEstablishmentManager, IsWineryReviewer from utils.permissions import IsCountryAdmin, IsEstablishmentManager, IsWineryReviewer
from utils.views import CreateDestroyGalleryViewMixin from utils.views import CreateDestroyGalleryViewMixin
from timetable.models import Timetable
from rest_framework import status
from rest_framework.response import Response
class EstablishmentMixinViews: class EstablishmentMixinViews:
@ -41,7 +43,7 @@ class EstablishmentScheduleRUDView(generics.RetrieveUpdateDestroyAPIView):
"""Establishment schedule RUD view""" """Establishment schedule RUD view"""
lookup_field = 'slug' lookup_field = 'slug'
serializer_class = ScheduleRUDSerializer serializer_class = ScheduleRUDSerializer
permission_classes = [IsWineryReviewer |IsEstablishmentManager] permission_classes = [IsWineryReviewer | IsEstablishmentManager]
def get_object(self): def get_object(self):
""" """
@ -75,6 +77,11 @@ class MenuListCreateView(generics.ListCreateAPIView):
serializer_class = serializers.MenuSerializers serializer_class = serializers.MenuSerializers
queryset = models.Menu.objects.all() queryset = models.Menu.objects.all()
permission_classes = [IsWineryReviewer | IsEstablishmentManager] permission_classes = [IsWineryReviewer | IsEstablishmentManager]
filter_backends = (DjangoFilterBackend,)
filterset_fields = (
'establishment',
'establishment__slug',
)
class MenuRUDView(generics.RetrieveUpdateDestroyAPIView): class MenuRUDView(generics.RetrieveUpdateDestroyAPIView):
@ -161,7 +168,7 @@ class EmailRUDView(generics.RetrieveUpdateDestroyAPIView):
class EmployeeListCreateView(generics.ListCreateAPIView): class EmployeeListCreateView(generics.ListCreateAPIView):
"""Emplyoee list create view.""" """Emplyoee list create view."""
permission_classes = (permissions.AllowAny, ) permission_classes = (permissions.AllowAny,)
filter_class = filters.EmployeeBackFilter filter_class = filters.EmployeeBackFilter
serializer_class = serializers.EmployeeBackSerializers serializer_class = serializers.EmployeeBackSerializers
queryset = models.Employee.objects.all() queryset = models.Employee.objects.all()
@ -170,7 +177,7 @@ class EmployeeListCreateView(generics.ListCreateAPIView):
class EstablishmentEmployeeListView(generics.ListCreateAPIView): class EstablishmentEmployeeListView(generics.ListCreateAPIView):
"""Establishment emplyoees list view.""" """Establishment emplyoees list view."""
permission_classes = (permissions.AllowAny, ) permission_classes = (permissions.AllowAny,)
serializer_class = serializers.EstablishmentEmployeeBackSerializer serializer_class = serializers.EstablishmentEmployeeBackSerializer
def get_queryset(self): def get_queryset(self):
@ -352,8 +359,8 @@ class EstablishmentEmployeeCreateView(generics.CreateAPIView):
class EstablishmentEmployeeDeleteView(generics.DestroyAPIView): class EstablishmentEmployeeDeleteView(generics.DestroyAPIView):
def _get_object_to_delete(self, establishment_id, employee_id): def _get_object_to_delete(self, establishment_id, employee_id):
result_qs = models.EstablishmentEmployee\ result_qs = models.EstablishmentEmployee \
.objects\ .objects \
.filter(establishment_id=establishment_id, employee_id=employee_id) .filter(establishment_id=establishment_id, employee_id=employee_id)
if not result_qs.exists(): if not result_qs.exists():
raise Http404 raise Http404
@ -371,7 +378,7 @@ class EstablishmentPositionListView(generics.ListAPIView):
"""Establishment positions list view.""" """Establishment positions list view."""
pagination_class = None pagination_class = None
permission_classes = (permissions.AllowAny, ) permission_classes = (permissions.AllowAny,)
queryset = models.Position.objects.all() queryset = models.Position.objects.all()
serializer_class = serializers.PositionBackSerializer serializer_class = serializers.PositionBackSerializer

View File

@ -87,7 +87,7 @@ class RestaurantSimilarListView(EstablishmentSimilarList):
"""Resource for getting a list of similar restaurants.""" """Resource for getting a list of similar restaurants."""
def get_queryset(self): def get_queryset(self):
"""Override get_queryset method""" """Overridden get_queryset method"""
return EstablishmentMixinView.get_queryset(self) \ return EstablishmentMixinView.get_queryset(self) \
.similar_restaurants(slug=self.kwargs.get('slug')) .similar_restaurants(slug=self.kwargs.get('slug'))
@ -96,11 +96,20 @@ class WinerySimilarListView(EstablishmentSimilarList):
"""Resource for getting a list of similar wineries.""" """Resource for getting a list of similar wineries."""
def get_queryset(self): def get_queryset(self):
"""Override get_queryset method""" """Overridden get_queryset method"""
return EstablishmentMixinView.get_queryset(self) \ return EstablishmentMixinView.get_queryset(self) \
.similar_wineries(slug=self.kwargs.get('slug')) .similar_wineries(slug=self.kwargs.get('slug'))
class ArtisanSimilarListView(EstablishmentSimilarList):
"""Resource for getting a list of similar artisans."""
def get_queryset(self):
"""Overridden get_queryset method"""
return EstablishmentMixinView.get_queryset(self) \
.similar_artisans(slug=self.kwargs.get('slug'))
class EstablishmentTypeListView(generics.ListAPIView): class EstablishmentTypeListView(generics.ListAPIView):
"""Resource for getting a list of establishment types.""" """Resource for getting a list of establishment types."""

View File

@ -0,0 +1,18 @@
# Generated by Django 2.2.7 on 2019-12-12 13:47
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('news', '0041_auto_20191211_1528'),
]
operations = [
migrations.AddField(
model_name='news',
name='duplication_date',
field=models.DateTimeField(blank=True, default=None, null=True, verbose_name='Duplication datetime'),
),
]

View File

@ -211,6 +211,8 @@ class News(GalleryModelMixin, BaseAttributes, TranslatedFieldsMixin, HasTagsMixi
verbose_name=_('banner')) verbose_name=_('banner'))
site = models.ForeignKey('main.SiteSettings', blank=True, null=True, site = models.ForeignKey('main.SiteSettings', blank=True, null=True,
on_delete=models.SET_NULL, verbose_name=_('site settings')) on_delete=models.SET_NULL, verbose_name=_('site settings'))
duplication_date = models.DateTimeField(blank=True, null=True, default=None,
verbose_name=_('Duplication datetime'))
objects = NewsQuerySet.as_manager() objects = NewsQuerySet.as_manager()
class Meta: class Meta:
@ -220,7 +222,16 @@ class News(GalleryModelMixin, BaseAttributes, TranslatedFieldsMixin, HasTagsMixi
verbose_name_plural = _('news') verbose_name_plural = _('news')
def __str__(self): def __str__(self):
return f'news: {self.slug}' return f'news: {next(iter(self.slugs.values()))}'
def create_duplicate(self, new_country, view_count_model):
self.pk = None
self.state = self.WAITING
self.slugs = {locale: f'{slug}-{new_country.code}' for locale, slug in self.slugs.items()}
self.country = new_country
self.views_count = view_count_model
self.duplication_date = timezone.now()
self.save()
@property @property
def is_publish(self): def is_publish(self):

View File

@ -13,6 +13,9 @@ from tag.serializers import TagBaseSerializer
from utils import exceptions as utils_exceptions from utils import exceptions as utils_exceptions
from utils.serializers import (TranslatedField, ProjectModelSerializer, from utils.serializers import (TranslatedField, ProjectModelSerializer,
FavoritesCreateSerializer, ImageBaseSerializer, CarouselCreateSerializer) FavoritesCreateSerializer, ImageBaseSerializer, CarouselCreateSerializer)
from rating import models as rating_models
from django.shortcuts import get_object_or_404
from utils.models import get_current_locale, get_default_locale
class AgendaSerializer(ProjectModelSerializer): class AgendaSerializer(ProjectModelSerializer):
@ -68,6 +71,13 @@ class NewsBaseSerializer(ProjectModelSerializer):
tags = TagBaseSerializer(read_only=True, many=True, source='visible_tags') tags = TagBaseSerializer(read_only=True, many=True, source='visible_tags')
in_favorites = serializers.BooleanField(allow_null=True, read_only=True) in_favorites = serializers.BooleanField(allow_null=True, read_only=True)
view_counter = serializers.IntegerField(read_only=True) view_counter = serializers.IntegerField(read_only=True)
slug = serializers.SerializerMethodField(read_only=True, allow_null=True)
def get_slug(self, obj):
if obj.slugs:
return obj.slugs.get(get_current_locale()) \
or obj.slugs.get(get_default_locale()) \
or next(iter(obj.slugs.values()))
class Meta: class Meta:
"""Meta class.""" """Meta class."""
@ -75,12 +85,12 @@ class NewsBaseSerializer(ProjectModelSerializer):
model = models.News model = models.News
fields = ( fields = (
'id', 'id',
'slug',
'title_translated', 'title_translated',
'subtitle_translated', 'subtitle_translated',
'is_highlighted', 'is_highlighted',
'news_type', 'news_type',
'tags', 'tags',
'slugs',
'view_counter', 'view_counter',
) )
@ -171,10 +181,13 @@ class NewsBackOfficeBaseSerializer(NewsBaseSerializer):
'title', 'title',
'backoffice_title', 'backoffice_title',
'subtitle', 'subtitle',
'slugs',
'is_published', 'is_published',
'duplication_date',
) )
extra_kwargs = { extra_kwargs = {
'backoffice_title': {'allow_null': False}, 'backoffice_title': {'allow_null': False},
'duplication_date': {'read_only': True},
} }
def create(self, validated_data): def create(self, validated_data):
@ -327,3 +340,24 @@ class NewsCarouselCreateSerializer(CarouselCreateSerializer):
'content_object': validated_data.pop('news') 'content_object': validated_data.pop('news')
}) })
return super().create(validated_data) return super().create(validated_data)
class NewsCloneCreateSerializer(NewsBackOfficeBaseSerializer,
NewsDetailSerializer):
"""Serializer for creating news clone."""
template_display = serializers.CharField(source='get_template_display',
read_only=True)
class Meta(NewsBackOfficeBaseSerializer.Meta, NewsDetailSerializer.Meta):
fields = NewsBackOfficeBaseSerializer.Meta.fields + NewsDetailSerializer.Meta.fields + (
'template_display',
)
read_only_fields = fields
def create(self, validated_data):
kwargs = self.context.get('request').parser_context.get('kwargs')
instance = get_object_or_404(models.News, pk=kwargs['pk'])
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

View File

@ -14,4 +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'),
] ]

View File

@ -7,7 +7,7 @@ from news import filters, models, serializers
from rating.tasks import add_rating from rating.tasks import add_rating
from utils.permissions import IsCountryAdmin, IsContentPageManager from utils.permissions import IsCountryAdmin, IsContentPageManager
from utils.views import CreateDestroyGalleryViewMixin, FavoritesCreateDestroyMixinView, CarouselCreateDestroyMixinView from utils.views import CreateDestroyGalleryViewMixin, FavoritesCreateDestroyMixinView, CarouselCreateDestroyMixinView
from utils.serializers import ImageBaseSerializer from utils.serializers import ImageBaseSerializer, EmptySerializer
class NewsMixinView: class NewsMixinView:
@ -167,3 +167,10 @@ class NewsCarouselCreateDestroyView(CarouselCreateDestroyMixinView):
_model = models.News _model = models.News
serializer_class = serializers.NewsCarouselCreateSerializer serializer_class = serializers.NewsCarouselCreateSerializer
class NewsCloneView(generics.CreateAPIView):
"""View for creating clone News"""
permission_classes = (permissions.AllowAny, )
serializer_class = serializers.NewsCloneCreateSerializer
queryset = models.News.objects.all()

View File

@ -222,6 +222,7 @@ class NewsDocumentSerializer(InFavoritesMixin, DocumentSerializer):
subtitle_translated = serializers.SerializerMethodField(allow_null=True) subtitle_translated = serializers.SerializerMethodField(allow_null=True)
news_type = NewsTypeSerializer() news_type = NewsTypeSerializer()
tags = TagsDocumentSerializer(many=True, source='visible_tags') tags = TagsDocumentSerializer(many=True, source='visible_tags')
slug = serializers.SerializerMethodField(allow_null=True)
class Meta: class Meta:
"""Meta class.""" """Meta class."""
@ -237,9 +238,13 @@ class NewsDocumentSerializer(InFavoritesMixin, DocumentSerializer):
'news_type', 'news_type',
'tags', 'tags',
'start', 'start',
'slugs', 'slug',
) )
@staticmethod
def get_slug(obj):
return get_translated_value(obj.slugs)
@staticmethod @staticmethod
def get_title_translated(obj): def get_title_translated(obj):
return get_translated_value(obj.title) return get_translated_value(obj.title)

View File

@ -3,7 +3,6 @@ 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,
GeoSpatialFilteringFilterBackend,
GeoSpatialOrderingFilterBackend, GeoSpatialOrderingFilterBackend,
OrderingFilterBackend, OrderingFilterBackend,
) )

View File

@ -123,19 +123,9 @@ class FiltersTagCategoryBaseSerializer(serializers.ModelSerializer):
return obj in ['open_now', ] return obj in ['open_now', ]
def get_param_name(self, obj): def get_param_name(self, obj):
if obj == 'service': if obj.index_name == 'wine-color':
return 'tags_id__in' return 'wine_colors_id__in'
return 'tags_id__in'
elif obj == 'pop':
return 'tags_id__in'
elif obj == 'open_now':
return 'open_now'
elif obj == 'wine_region':
return 'wine_region_id__in'
return '%s__in' % obj.index_name
def get_fields(self, *args, **kwargs): def get_fields(self, *args, **kwargs):
fields = super(FiltersTagCategoryBaseSerializer, self).get_fields() fields = super(FiltersTagCategoryBaseSerializer, self).get_fields()

View File

@ -1,17 +1,15 @@
"""Tag views.""" """Tag views."""
from django.conf import settings from django.conf import settings
from rest_framework import generics from rest_framework import generics, mixins, permissions, status, viewsets
from rest_framework import mixins
from rest_framework import permissions
from rest_framework import status
from rest_framework import viewsets
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.serializers import ValidationError
from django.utils.translation import gettext_lazy as _
from search_indexes import views as search_views
from location.models import WineRegion from location.models import WineRegion
from tag import filters from product.models import ProductType
from tag import models from tag import filters, models, serializers
from tag import serializers
class ChosenTagsView(generics.ListAPIView, viewsets.GenericViewSet): class ChosenTagsView(generics.ListAPIView, viewsets.GenericViewSet):
@ -61,14 +59,9 @@ class TagCategoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
# User`s views & viewsets # User`s views & viewsets
class FiltersTagCategoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): class FiltersTagCategoryViewSet(TagCategoryViewSet):
"""ViewSet for TagCategory model.""" """ViewSet for TagCategory model."""
filterset_class = filters.TagCategoryFilterSet
pagination_class = None
permission_classes = (permissions.AllowAny,)
queryset = models.TagCategory.objects.with_tags().with_base_related(). \
distinct()
serializer_class = serializers.FiltersTagCategoryBaseSerializer serializer_class = serializers.FiltersTagCategoryBaseSerializer
def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):
@ -92,7 +85,7 @@ class FiltersTagCategoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
if params_type == 'restaurant': if params_type == 'restaurant':
additional_flags += ['toque_number', 'works_noon', 'works_evening', 'works_now'] additional_flags += ['toque_number', 'works_noon', 'works_evening', 'works_now']
elif params_type == 'winery': elif params_type in ['winery', 'wine']:
additional_flags += ['wine_region'] additional_flags += ['wine_region']
elif params_type == 'artisan': elif params_type == 'artisan':
@ -114,7 +107,7 @@ class FiltersTagCategoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
} }
result_list.append(toques) result_list.append(toques)
if filter_flags['wine_region']: if request.query_params.get('product_type') == ProductType.WINE:
wine_region_id = query_params.get('wine_region_id__in') wine_region_id = query_params.get('wine_region_id__in')
if str(wine_region_id).isdigit(): if str(wine_region_id).isdigit():
@ -185,12 +178,77 @@ class FiltersTagCategoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
} }
result_list.append(works_at_weekday) result_list.append(works_at_weekday)
if 'tags_id__in' in query_params: search_view_class = self.define_search_view_by_request(request)
# filtering by params_type and tags id facets = search_view_class.as_view({'get': 'list'})(self.mutate_request(self.request)).data['facets']
# todo: result_list.append( filtering_data ) return Response(self.remove_empty_filters(result_list, facets))
pass
return Response(result_list) @staticmethod
def mutate_request(request):
"""Remove all filtering get params and remove s_ from the rest of them"""
request.GET._mutable = True
for name in request.query_params.copy().keys():
value = request.query_params.pop(name)
if name.startswith('s_'):
request.query_params[name[2:]] = value[0]
request.GET._mutable = False
return request._request
@staticmethod
def define_search_view_by_request(request):
request.GET._mutable = True
if request.query_params.get('items'):
items = request.query_params.pop('items')[0]
else:
raise ValidationError({'detail': _('Missing required "items" parameter')})
item_to_class = {
'news': search_views.NewsDocumentViewSet,
'establishments': search_views.EstablishmentDocumentViewSet,
'products': search_views.ProductDocumentViewSet,
}
klass = item_to_class.get(items)
if klass is None:
raise ValidationError({'detail': _('news/establishments/products')})
request.GET._mutable = False
return klass
@staticmethod
def remove_empty_filters(filters, facets):
# parse facets
if facets.get('_filter_tag'):
tags_to_preserve = list(map(lambda el: el['key'], facets['_filter_tag']['tag']['buckets']))
if facets.get('_filter_wine_colors'):
wine_colors_to_preserve = list(map(lambda el: el['key'], facets['_filter_wine_colors']['wine_colors']['buckets']))
if facets.get('_filter_wine_region_id'):
wine_regions_to_preserve = list(map(lambda el: el['key'], facets['_filter_wine_region_id']['wine_region_id']['buckets']))
if facets.get('_filter_toque_number'):
toque_numbers = list(map(lambda el: el['key'], facets['_filter_toque_number']['toque_number']['buckets']))
if facets.get('_filter_works_noon'):
works_noon = list(map(lambda el: el['key'], facets['_filter_works_noon']['works_noon']['buckets']))
if facets.get('_filter_works_evening'):
works_evening = list(map(lambda el: el['key'], facets['_filter_works_evening']['works_evening']['buckets']))
if facets.get('_filter_works_at_weekday'):
works_at_weekday = list(map(lambda el: el['key'], facets['_filter_works_at_weekday']['works_at_weekday']['buckets']))
if facets.get('_filter_works_now'):
works_now = list(map(lambda el: el['key'], facets['_filter_works_now']['works_now']['buckets']))
# remove empty filters
for category in filters:
param_name = category.get('param_name')
if param_name == 'tags_id__in':
category['filters'] = list(filter(lambda tag: tag['id'] in tags_to_preserve, category['filters']))
elif param_name == 'wine_colors_id__in':
category['filters'] = list(filter(lambda tag: tag['id'] in wine_colors_to_preserve, category['filters']))
elif param_name == 'wine_region_id__in':
category['filters'] = list(filter(lambda tag: tag['id'] in wine_regions_to_preserve, category['filters']))
elif param_name == 'toque_number__in':
category['filters'] = list(filter(lambda tag: tag['id'] in toque_numbers, category['filters']))
elif param_name == 'works_noon__in':
category['filters'] = list(filter(lambda tag: tag['id'] in works_noon, category['filters']))
elif param_name == 'works_evening__in':
category['filters'] = list(filter(lambda tag: tag['id'] in works_evening, category['filters']))
elif param_name == 'works_at_weekday__in':
category['filters'] = list(filter(lambda tag: tag['id'] in works_at_weekday, category['filters']))
return filters
# BackOffice user`s views & viewsets # BackOffice user`s views & viewsets

View File

@ -1224,6 +1224,21 @@ class Footers(MigrateMixin):
db_table = 'footers' db_table = 'footers'
class OwnershipAffs(MigrateMixin):
using = 'legacy'
role = models.CharField(max_length=255, blank=True, null=True)
state = models.CharField(max_length=255, blank=True, null=True)
account_id = models.IntegerField(blank=True, null=True)
establishment_id = models.IntegerField(blank=True, null=True)
created_at = models.DateTimeField()
updated_at = models.DateTimeField()
requester_id = models.IntegerField(blank=True, null=True)
class Meta:
managed = False
db_table = 'ownership_affs'
class Panels(MigrateMixin): class Panels(MigrateMixin):
using = 'legacy' using = 'legacy'
@ -1239,19 +1254,3 @@ class Panels(MigrateMixin):
class Meta: class Meta:
managed = False managed = False
db_table = 'panels' db_table = 'panels'
class OwnershipAffs(MigrateMixin):
using = 'legacy'
role = models.CharField(max_length=255, blank=True, null=True)
state = models.CharField(max_length=255, blank=True, null=True)
account_id = models.IntegerField(blank=True, null=True)
establishment_id = models.IntegerField(blank=True, null=True)
created_at = models.DateTimeField()
updated_at = models.DateTimeField()
requester_id = models.IntegerField(blank=True, null=True)
class Meta:
managed = False
db_table = 'ownership_affs'

12
db_migration_resolve.txt Normal file
View File

@ -0,0 +1,12 @@
В случае возникновения проблемы с применением миграции account 0027:
1 Удаляем unique together constrain для app - account
ALTER TABLE account_userrole
DROP CONSTRAINT account_userrole_user_id_role_id_26fa14c4_uniq;
2 Правим миграцию 0023
migrations.AlterUniqueTogether(
name='userrole',
unique_together=set(),
),
3 Применяем account 0027
4 Возвращаем миграцию account 0023, в исходное состояние