Merge remote-tracking branch 'origin/develop' into owner_list

# Conflicts:
#	apps/transfer/models.py
This commit is contained in:
Dmitriy Kuzmenko 2019-12-13 11:08:18 +03:00
commit f6427e732a
28 changed files with 479 additions and 89 deletions

View File

@ -10,4 +10,5 @@ urlpatterns = [
path('user-role/', views.UserRoleLstView.as_view(), name='user-role-list-create'),
path('user/', views.UserLstView.as_view(), name='user-create-list'),
path('user/<int:id>/', views.UserRUDView.as_view(), name='user-rud'),
path('user/<int:id>/csv', views.get_user_csv, name='user-csv'),
]

View File

@ -1,6 +1,9 @@
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import generics, permissions
from rest_framework.filters import OrderingFilter
import csv
from django.http import HttpResponse, HttpResponseNotFound
from rest_framework.authtoken.models import Token
from account import models
from account.models import User
@ -46,3 +49,69 @@ class UserRUDView(generics.RetrieveUpdateDestroyAPIView):
serializer_class = serializers.BackDetailUserSerializer
permission_classes = (permissions.IsAdminUser,)
lookup_field = 'id'
def get_user_csv(request, id):
# fields = ["id", "uuid", "nickname", "locale", "country_code", "city", "role", "consent_purpose", "consent_at",
# "last_seen_at", "created_at", "updated_at", "email", "is_admin", "ezuser_id", "ez_user_id",
# "encrypted_password", "reset_password_token", "reset_password_sent_at", "remember_created_at",
# "sign_in_count", "current_sign_in_at", "last_sign_in_at", "current_sign_in_ip", "last_sign_in_ip",
# "confirmation_token", "confirmed_at", "confirmation_sent_at", "unconfirmed_email", "webpush_subscription"]
# uuid == id
#
# Не найдены:
# consent_purpose
# consent_at
# ezuser_id
# ez_user_id
# remember_created_at
# sign_in_count
# current_sign_in_at
# current_sign_in_ip
# last_sign_in_ip
# confirmed_at
# confirmation_sent_at
# webpush_subscription
#
# country_code не получить - клиент не привязан к стране
try:
user = User.objects.get(id=id)
except User.DoesNotExist:
return HttpResponseNotFound("User not found")
try:
roles = " ".join([role for role in user.roles])
except:
roles = ""
token, _ = Token.objects.get_or_create(user=user)
fields = {
"id": user.id,
"uuid": user.id,
"username": getattr(user, "username", ""),
"locale": getattr(user, "locale", ""),
"city": getattr(user, "city", ""),
"role": roles,
"created_at": getattr(user, "date_joined", ""),
"updated_at": user.last_login,
"email": user.email,
"is_admin": user.is_superuser,
"encrypted_password": user.password,
"reset_password_token": token.key,
"reset_password_sent_at": token.created, # TODO: не уверен в назначении поля, лучше проверить
"last_sign_in_at": user.last_login, # Повтор?
"confirmation_token": user.confirm_email_token,
"unconfirmed_email": 1 if user.unconfirmed_email else 0
}
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = f'attachment; filename="{user.email}.csv"'
writer = csv.writer(response)
writer.writerow(fields.keys())
writer.writerow(fields.values())
return response

View File

@ -9,11 +9,17 @@ from utils.views import BindObjectMixin
class CollectionViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
"""ViewSet for Collection model."""
pagination_class = None
# pagination_class = None
permission_classes = (permissions.AllowAny,)
queryset = models.Collection.objects.all()
serializer_class = serializers.CollectionBackOfficeSerializer
def get_queryset(self):
"""Overridden method 'get_queryset'."""
qs = models.Collection.objects.all().order_by('-created')
if self.request.country_code:
qs = qs.by_country_code(self.request.country_code)
return qs
class CollectionBackOfficeViewSet(mixins.CreateModelMixin,
mixins.UpdateModelMixin,

View File

@ -0,0 +1,17 @@
# Generated by Django 2.2.7 on 2019-12-11 15:28
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('gallery', '0006_merge_20191027_1758'),
]
operations = [
migrations.AlterModelOptions(
name='image',
options={'ordering': ['-modified'], 'verbose_name': 'Image', 'verbose_name_plural': 'Images'},
),
]

View File

@ -34,6 +34,7 @@ class Image(ProjectBaseMixin, SORLImageMixin, PlatformMixin):
"""Meta class."""
verbose_name = _('Image')
verbose_name_plural = _('Images')
ordering = ['-modified']
def __str__(self):
"""String representation"""

View File

@ -1,8 +1,9 @@
from django.conf import settings
from django.core.validators import MinValueValidator, MaxValueValidator
from django.core.files.base import ContentFile
from rest_framework import serializers
from sorl.thumbnail.parsers import parse_crop
from sorl.thumbnail.parsers import ThumbnailParseError
from sorl.thumbnail import get_thumbnail
from sorl.thumbnail.parsers import parse_crop, ThumbnailParseError
from django.utils.translation import gettext_lazy as _
from . import models
@ -88,15 +89,23 @@ class CropImageSerializer(ImageSerializer):
quality = validated_data.pop('quality')
crop = validated_data.pop('crop')
crop_params = {
'geometry': f'{width}x{height}',
'quality': quality,
'crop': crop,
}
cropped_image = self._image.get_cropped_image(**crop_params)
image = self._image
image.pk = None
crop_params['geometry_string'] = crop_params.pop('geometry')
resized = get_thumbnail(self._image.image, **crop_params)
image.image.save(resized.name, ContentFile(resized.read()), True)
image.save()
if image and width and height:
setattr(image,
'cropped_image',
image.get_cropped_image(
geometry=f'{width}x{height}',
quality=quality,
crop=crop))
cropped_image)
return image
@property

View File

@ -10,6 +10,7 @@ urlpatterns = [
path('addresses/<int:pk>/', views.AddressRUDView.as_view(), name='address-RUD'),
path('cities/', views.CityListCreateView.as_view(), name='city-list-create'),
path('cities/all/', views.CityListSearchView.as_view(), name='city-list-create'),
path('cities/<int:pk>/', views.CityRUDView.as_view(), name='city-retrieve'),
path('cities/<int:pk>/gallery/', views.CityGalleryListView.as_view(),
name='gallery-list'),

View File

@ -37,6 +37,15 @@ class CityListCreateView(common.CityViewMixin, generics.ListCreateAPIView):
filter_class = filters.CityBackFilter
class CityListSearchView(common.CityViewMixin, generics.ListCreateAPIView):
"""Create view for model City."""
serializer_class = serializers.CitySerializer
permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin]
queryset = models.City.objects.all()
filter_class = filters.CityBackFilter
pagination_class = None
class CityRUDView(common.CityViewMixin, generics.RetrieveUpdateDestroyAPIView):
"""RUD view for model City."""
serializer_class = serializers.CitySerializer

View File

@ -0,0 +1,38 @@
from django.core.management.base import BaseCommand
from tqdm import tqdm
from account.models import User
from main.models import Panel, SiteSettings
from transfer.models import Panels
class Command(BaseCommand):
help = '''Add panels from legacy DB.'''
def handle(self, *args, **kwargs):
objects = []
deleted = 0
panels_list = Panels.objects.filter(name__isnull=False)
# remove existing panel
exist_panel = Panel.objects.filter(old_id__isnull=False)
if exist_panel.exists():
deleted = exist_panel.count()
exist_panel.delete()
for old_panel in tqdm(panels_list, desc='Add panels'):
site = SiteSettings.objects.filter(old_id=old_panel.site_id).first()
user = User.objects.filter(old_id=old_panel.site_id).first()
if site:
new_panel = Panel(
old_id=old_panel.id,
user=user,
site=site,
name=old_panel.name,
display=old_panel.display,
description=old_panel.description,
query=old_panel.query,
)
objects.append(new_panel)
Panel.objects.bulk_create(objects)
self.stdout.write(
self.style.WARNING(f'Created {len(objects)}/Deleted {deleted} footer objects.'))

View File

@ -0,0 +1,36 @@
# Generated by Django 2.2.7 on 2019-12-12 12:00
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('main', '0041_auto_20191211_0631'),
]
operations = [
migrations.CreateModel(
name='Panel',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(default=django.utils.timezone.now, editable=False, verbose_name='Date created')),
('modified', models.DateTimeField(auto_now=True, verbose_name='Date updated')),
('name', models.CharField(max_length=255, verbose_name='name')),
('display', models.CharField(blank=True, choices=[('table', 'table'), ('table', 'mailing')], default=None, max_length=255, null=True, verbose_name='display')),
('description', models.CharField(blank=True, default=None, max_length=255, null=True, verbose_name='description')),
('query', models.TextField(blank=True, default=None, null=True, verbose_name='query')),
('old_id', models.IntegerField(blank=True, default=None, null=True, verbose_name='old id')),
('site', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='main.SiteSettings', verbose_name='site')),
('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='user')),
],
options={
'verbose_name': 'panel',
'verbose_name_plural': 'panels',
},
),
]

View File

@ -361,3 +361,46 @@ class Footer(ProjectBaseMixin):
)
about_us = models.TextField(_('about_us'))
copyright = models.TextField(_('copyright'))
class PanelQuerySet(models.QuerySet):
"""Panels QuerySet."""
class Panel(ProjectBaseMixin):
"""Custom panel model with stored SQL query."""
TABLE = 'table'
MAILING = 'table'
DISPLAY_CHOICES = (
(TABLE, _('table')),
(MAILING, _('mailing'))
)
name = models.CharField(_('name'), max_length=255)
display = models.CharField(
_('display'), max_length=255, choices=DISPLAY_CHOICES,
blank=True, null=True, default=None
)
description = models.CharField(
_('description'), max_length=255, blank=True, null=True, default=None)
query = models.TextField(_('query'), blank=True, null=True, default=None)
user = models.ForeignKey(
'account.User', verbose_name=_('user'), null=True,
on_delete=models.SET_NULL)
site = models.ForeignKey(
'main.SiteSettings', verbose_name=_('site'), null=True,
on_delete=models.SET_NULL)
old_id = models.IntegerField(
_('old id'), null=True, blank=True, default=None)
objects = PanelQuerySet.as_manager()
class Meta:
verbose_name = _('panel')
verbose_name_plural = _('panels')
def __str__(self):
return self.name
def execute_query(self):
pass

View File

@ -5,6 +5,8 @@ from rest_framework import serializers
from location.serializers import CountrySerializer
from main import models
from utils.serializers import ProjectModelSerializer, TranslatedField, RecursiveFieldSerializer
from account.serializers.back import BackUserSerializer
from account.models import User
class FeatureSerializer(serializers.ModelSerializer):
@ -265,8 +267,32 @@ class PageTypeBaseSerializer(serializers.ModelSerializer):
class ContentTypeBackSerializer(serializers.ModelSerializer):
"""Serializer fro model ContentType."""
"""Serializer for model ContentType."""
class Meta:
model = ContentType
fields = '__all__'
class PanelSerializer(serializers.ModelSerializer):
"""Serializer for Custom panel."""
user_id = serializers.PrimaryKeyRelatedField(
queryset=User.objects.all(),
source='user',
write_only=True
)
user = BackUserSerializer(read_only=True)
class Meta:
model = models.Panel
fields = [
'id',
'name',
'display',
'description',
'query',
'created',
'modified',
'user',
'user_id'
]

View File

@ -21,7 +21,11 @@ urlpatterns = [
path('footer/', views.FooterBackView.as_view(), name='footer-list-create'),
path('footer/<int:pk>/', views.FooterRUDBackView.as_view(), name='footer-rud'),
path('page-types/', views.PageTypeListCreateView.as_view(),
name='page-types-list-create')
name='page-types-list-create'),
path('panels/', views.PanelsListCreateView.as_view(), name='panels'),
path('panels/<int:pk>/', views.PanelsListCreateView.as_view(), name='panels-rud'),
# path('panels/<int:pk>/execute/', views.PanelsView.as_view(), name='panels-execute')
]

View File

@ -4,7 +4,7 @@ from rest_framework import generics, permissions
from main import serializers
from main.filters import AwardFilter
from main.models import Award, Footer, PageType
from main.models import Award, Footer, PageType, Panel
from main.views import SiteSettingsView, SiteListView
@ -89,3 +89,21 @@ class PageTypeListCreateView(generics.ListCreateAPIView):
pagination_class = None
serializer_class = serializers.PageTypeBaseSerializer
queryset = PageType.objects.all()
class PanelsListCreateView(generics.ListCreateAPIView):
"""Custom panels view."""
permission_classes = (
permissions.IsAdminUser,
)
serializer_class = serializers.PanelSerializer
queryset = Panel.objects.all()
class PanelsRUDView(generics.RetrieveUpdateDestroyAPIView):
"""Custom panels view."""
permission_classes = (
permissions.IsAdminUser,
)
serializer_class = serializers.PanelSerializer
queryset = Panel.objects.all()

View File

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

View File

@ -0,0 +1,18 @@
# Generated by Django 2.2.7 on 2019-12-11 15:28
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('gallery', '0007_auto_20191211_1528'),
('news', '0040_remove_news_slug'),
]
operations = [
migrations.AlterUniqueTogether(
name='newsgallery',
unique_together={('news', 'image')},
),
]

View File

@ -320,4 +320,4 @@ class NewsGallery(IntermediateGalleryModelMixin):
"""NewsGallery meta class."""
verbose_name = _('news gallery')
verbose_name_plural = _('news galleries')
unique_together = (('news', 'is_main'), ('news', 'image'))
unique_together = [['news', 'image'],]

View File

@ -243,6 +243,16 @@ class NewsBackOfficeGallerySerializer(serializers.ModelSerializer):
"""Get url kwargs from request."""
return self.context.get('request').parser_context.get('kwargs')
def create(self, validated_data):
news_pk = self.get_request_kwargs().get('pk')
image_id = self.get_request_kwargs().get('image_id')
qs = models.NewsGallery.objects.filter(image_id=image_id, news_id=news_pk)
instance = qs.first()
if instance:
qs.update(**validated_data)
return instance
return super().create(validated_data)
def validate(self, attrs):
"""Override validate method."""
news_pk = self.get_request_kwargs().get('pk')
@ -259,8 +269,8 @@ class NewsBackOfficeGallerySerializer(serializers.ModelSerializer):
news = news_qs.first()
image = image_qs.first()
if image in news.gallery.all():
raise serializers.ValidationError({'detail': _('Image is already added.')})
# if image in news.gallery.all():
# raise serializers.ValidationError({'detail': _('Image is already added.')})
attrs['news'] = news
attrs['image'] = image

View File

@ -0,0 +1,19 @@
# Generated by Django 2.2.7 on 2019-12-12 09:26
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('product', '0020_merge_20191209_0911'),
]
operations = [
migrations.AlterField(
model_name='product',
name='product_type',
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='products', to='product.ProductType', verbose_name='Type'),
),
]

View File

@ -171,7 +171,7 @@ class Product(GalleryModelMixin, TranslatedFieldsMixin, BaseAttributes,
default=None, help_text='{"en-GB":"some text"}')
available = models.BooleanField(_('available'), default=True)
product_type = models.ForeignKey(ProductType, on_delete=models.PROTECT,
null=True,
null=True, blank=True, default=None,
related_name='products', verbose_name=_('Type'))
subtypes = models.ManyToManyField(ProductSubType, blank=True,
related_name='products',

View File

@ -5,7 +5,7 @@ from search_indexes.utils import OBJECT_FIELD_PROPERTIES
from product import models
ProductIndex = Index(settings.ELASTICSEARCH_INDEX_NAMES.get(__name__, 'product'))
ProductIndex.settings(number_of_shards=5, number_of_replicas=2, mapping={'total_fields':{'limit': 3000}})
ProductIndex.settings(number_of_shards=5, number_of_replicas=2, mapping={'total_fields': {'limit': 3000}})
@ProductIndex.doc_type
@ -14,12 +14,13 @@ class ProductDocument(Document):
description = fields.ObjectField(attr='description_indexing',
properties=OBJECT_FIELD_PROPERTIES)
product_type = fields.ObjectField(properties={
'id': fields.IntegerField(),
'name': fields.ObjectField(attr='name_indexing', properties=OBJECT_FIELD_PROPERTIES),
'index_name': fields.KeywordField(),
'use_subtypes': fields.BooleanField(),
})
product_type = fields.ObjectField(
properties={
'id': fields.IntegerField(),
'name': fields.ObjectField(attr='name_indexing', properties=OBJECT_FIELD_PROPERTIES),
'index_name': fields.KeywordField(),
},
)
subtypes = fields.ObjectField(
properties={
'id': fields.IntegerField(),
@ -54,15 +55,12 @@ class ProductDocument(Document):
),
'address': fields.ObjectField(
properties={
'city': fields.ObjectField(
properties={
'country': fields.ObjectField(
properties={
'code': fields.KeywordField()
}
)
}
)
'id': fields.IntegerField(),
'street_name_1': fields.TextField(
fields={'raw': fields.KeywordField()}
),
'postal_code': fields.KeywordField(),
'coordinates': fields.GeoPointField(attr='location_field_indexing'),
}
)
}
@ -155,7 +153,7 @@ class ProductDocument(Document):
name_ru = fields.TextField(attr='display_name', analyzer='russian')
name_fr = fields.TextField(attr='display_name', analyzer='french')
favorites_for_users = fields.ListField(field=fields.IntegerField())
created = fields.DateField(attr='created') # publishing date (?)
created = fields.DateField(attr='created') # publishing date (?)
class Django:
model = models.Product

View File

@ -40,6 +40,8 @@ class ProductSubtypeDocumentSerializer(serializers.Serializer):
name_translated = serializers.SerializerMethodField()
def get_name_translated(self, obj):
if isinstance(obj, dict):
return get_translated_value(obj.get('name'))
return get_translated_value(obj.name)
@ -93,7 +95,7 @@ class TagDocumentSerializer(serializers.Serializer):
return get_translated_value(obj.label)
class ProductTypeDocumentSerializer(serializers.Serializer):
class ProductTypeSerializer(serializers.Serializer):
"""Product type ES document serializer."""
id = serializers.IntegerField()
@ -102,8 +104,13 @@ class ProductTypeDocumentSerializer(serializers.Serializer):
@staticmethod
def get_name_translated(obj):
if isinstance(obj, dict):
return get_translated_value(obj.get('name'))
return get_translated_value(obj.name)
def get_attribute(self, instance):
return instance.product_type if instance and instance.product_type else None
class CityDocumentShortSerializer(serializers.Serializer):
"""City serializer for ES Document,"""
@ -114,7 +121,6 @@ class CityDocumentShortSerializer(serializers.Serializer):
class CountryDocumentSerializer(serializers.Serializer):
id = serializers.IntegerField()
code = serializers.CharField(allow_null=True)
svg_image = serializers.CharField()
@ -122,11 +128,12 @@ class CountryDocumentSerializer(serializers.Serializer):
@staticmethod
def get_name_translated(obj):
if isinstance(obj, dict):
return get_translated_value(obj.get('name'))
return get_translated_value(obj.name)
class AnotherCityDocumentShortSerializer(CityDocumentShortSerializer):
country = CountryDocumentSerializer()
def to_representation(self, instance):
@ -136,19 +143,6 @@ class AnotherCityDocumentShortSerializer(CityDocumentShortSerializer):
return None
class ProductEstablishmentDocumentSerializer(serializers.Serializer):
"""Related to Product Establishment ES document serializer."""
id = serializers.IntegerField()
name = serializers.CharField()
slug = serializers.CharField()
index_name = serializers.CharField()
city = AnotherCityDocumentShortSerializer()
def get_attribute(self, instance):
return instance.establishment if instance and instance.establishment else None
class AddressDocumentSerializer(serializers.Serializer):
"""Address serializer for ES Document."""
@ -171,6 +165,28 @@ class AddressDocumentSerializer(serializers.Serializer):
return None
class PSAddressDocumentSerializer(serializers.Serializer):
"""Address serializer for ES Document."""
id = serializers.IntegerField()
street_name_1 = serializers.CharField()
postal_code = serializers.CharField()
class ProductEstablishmentSerializer(serializers.Serializer):
"""Related to Product Establishment ES document serializer."""
id = serializers.IntegerField()
name = serializers.CharField()
slug = serializers.CharField()
index_name = serializers.CharField()
city = AnotherCityDocumentShortSerializer()
address = PSAddressDocumentSerializer(allow_null=True)
def get_attribute(self, instance):
return instance.establishment if instance and instance.establishment else None
class ScheduleDocumentSerializer(serializers.Serializer):
"""Schedule serializer for ES Document"""
@ -285,15 +301,15 @@ class EstablishmentDocumentSerializer(InFavoritesMixin, DocumentSerializer):
)
class ProductDocumentSerializer(InFavoritesMixin, DocumentSerializer):
class ProductDocumentSerializer(InFavoritesMixin):
"""Product document serializer"""
tags = TagsDocumentSerializer(many=True, source='related_tags')
subtypes = ProductSubtypeDocumentSerializer(many=True, allow_null=True)
wine_colors = TagDocumentSerializer(many=True)
grape_variety = TagDocumentSerializer(many=True)
product_type = ProductTypeDocumentSerializer(allow_null=True)
establishment_detail = ProductEstablishmentDocumentSerializer(source='establishment', allow_null=True)
product_type = ProductTypeSerializer(allow_null=True)
establishment_detail = ProductEstablishmentSerializer(source='establishment', allow_null=True)
wine_origins = WineOriginSerializer(many=True)
class Meta:
@ -317,7 +333,6 @@ class ProductDocumentSerializer(InFavoritesMixin, DocumentSerializer):
'subtypes',
'wine_colors',
'grape_variety',
'establishment_detail',
'average_price',
'created',
'wine_origins',

View File

@ -12,8 +12,8 @@ def update_document(sender, **kwargs):
instance = kwargs['instance']
app_label_model_name_to_filter = {
('location','country'): 'address__city__country',
('location','city'): 'address__city',
('location', 'country'): 'address__city__country',
('location', 'city'): 'address__city',
('location', 'address'): 'address',
# todo: remove after migration
('establishment', 'establishmenttype'): 'establishment_type',
@ -34,8 +34,8 @@ def update_news(sender, **kwargs):
model_name = sender._meta.model_name
instance = kwargs['instance']
app_label_model_name_to_filter = {
('location','country'): 'country',
('news','newstype'): 'news_type',
('location', 'country'): 'country',
('news', 'newstype'): 'news_type',
('tag', 'tag'): 'tags',
}
filter_name = app_label_model_name_to_filter.get((app_label, model_name))
@ -52,9 +52,9 @@ def update_product(sender, **kwargs):
model_name = sender._meta.model_name
instance = kwargs['instance']
app_label_model_name_to_filter = {
('product','productstandard'): 'standards',
('product', 'productstandard'): 'standards',
('product', 'producttype'): 'product_type',
('tag','tag'): 'tags',
('tag', 'tag'): 'tags',
('location', 'wineregion'): 'wine_region',
('location', 'winesubregion'): 'wine_sub_region',
('location', 'winevillage'): 'wine_village',

View File

@ -78,9 +78,30 @@ class FiltersTagCategoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
result_list = serializer.data
query_params = request.query_params
params_type = query_params['type']
params_type = query_params.get('type')
if query_params.get('establishment_type'):
params_type = query_params.get('establishment_type')
elif query_params.get('product_type'):
params_type = query_params.get('product_type')
if params_type == 'restaurant' and 'toque_number__in' in query_params:
week_days = ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")
flags = ('toque_number', 'wine_region', 'works_noon', 'works_evening', 'works_now', 'works_at_weekday')
filter_flags = {flag_name: False for flag_name in flags}
additional_flags = []
if params_type == 'restaurant':
additional_flags += ['toque_number', 'works_noon', 'works_evening', 'works_now']
elif params_type == 'winery':
additional_flags += ['wine_region']
elif params_type == 'artisan':
additional_flags += ['works_now', 'works_at_weekday']
for flag_name in additional_flags:
filter_flags[flag_name] = True
if filter_flags['toque_number']:
toques = {
"index_name": "toque_number",
"label_translated": "Toques",
@ -93,28 +114,29 @@ class FiltersTagCategoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
}
result_list.append(toques)
if params_type == 'winery' and 'wine_region_id__in' in query_params:
try:
wine_region_id = int(query_params['wine_region_id__in'])
if filter_flags['wine_region']:
wine_region_id = query_params.get('wine_region_id__in')
wine_regions = {
"index_name": "wine_region",
"label_translated": "Wine region",
"param_name": "wine_region_id__in",
"filters": [{
"id": obj.id,
"index_name": obj.name.lower().replace(' ', '_'),
"label_translated": obj.name
} for obj in WineRegion.objects.filter(id=wine_region_id)]
}
if str(wine_region_id).isdigit():
queryset = WineRegion.objects.filter(id=int(wine_region_id))
result_list.append(wine_regions)
else:
queryset = WineRegion.objects.all()
except ValueError:
pass
wine_regions = {
"index_name": "wine_region",
"label_translated": "Wine region",
"param_name": "wine_region_id__in",
"filters": [{
"id": obj.id,
"index_name": obj.name.lower().replace(' ', '_'),
"label_translated": obj.name
} for obj in queryset]
}
if params_type == 'restaurant' and 'works_noon__in' in query_params:
week_days = ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")
result_list.append(wine_regions)
if filter_flags['works_noon']:
works_noon = {
"index_name": "works_noon",
"label_translated": "Open noon",
@ -127,8 +149,8 @@ class FiltersTagCategoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
}
result_list.append(works_noon)
if params_type == 'restaurant' and 'works_evening__in' in query_params:
week_days = ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")
if filter_flags['works_evening']:
works_evening = {
"index_name": "works_evening",
"label_translated": "Open evening",
@ -141,7 +163,7 @@ class FiltersTagCategoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
}
result_list.append(works_evening)
if params_type in ('restaurant', 'artisan') and 'works_now' in query_params:
if filter_flags['works_now']:
works_now = {
"index_name": "open_now",
"label_translated": "Open now",
@ -150,6 +172,19 @@ class FiltersTagCategoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
}
result_list.append(works_now)
if filter_flags['works_at_weekday']:
works_at_weekday = {
"index_name": "works_at_weekday",
"label_translated": "Works at weekday",
"param_name": "works_at_weekday__in",
"filters": [{
"id": weekday,
"index_name": week_days[weekday].lower(),
"label_translated": week_days[weekday]
} for weekday in range(7)]
}
result_list.append(works_at_weekday)
if 'tags_id__in' in query_params:
# filtering by params_type and tags id
# todo: result_list.append( filtering_data )

View File

@ -1224,6 +1224,23 @@ class Footers(MigrateMixin):
db_table = 'footers'
class Panels(MigrateMixin):
using = 'legacy'
name = models.CharField(max_length=255, blank=True, null=True)
display = models.CharField(max_length=255, blank=True, null=True)
description = models.CharField(max_length=255, blank=True, null=True)
query = models.TextField(blank=True, null=True)
created_at = models.DateTimeField(blank=True, null=True)
updated_at = models.DateTimeField(blank=True, null=True)
account_id = models.IntegerField(blank=True, null=True)
site_id = models.IntegerField(blank=True, null=True)
class Meta:
managed = False
db_table = 'panels'
class OwnershipAffs(MigrateMixin):
using = 'legacy'

View File

@ -3,6 +3,7 @@ import logging
import random
import re
import string
from collections import namedtuple
import requests
from django.conf import settings
@ -124,3 +125,10 @@ def absolute_url_decorator(func):
def get_point_from_coordinates(latitude: str, longitude: str):
if latitude and longitude:
return Point(x=longitude, y=latitude, srid=4326)
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()]

View File

@ -16,8 +16,6 @@ services:
- .:/code
# PostgreSQL database
db:
build:

View File

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