Merge branch 'develop' into feature/collect
This commit is contained in:
commit
954d515a5a
|
|
@ -87,3 +87,8 @@ class MenuAdmin(BaseModelAdminMixin, admin.ModelAdmin):
|
|||
return obj.category_translated
|
||||
|
||||
category_translated.short_description = _('category')
|
||||
|
||||
|
||||
@admin.register(models.RatingStrategy)
|
||||
class RatingStrategyAdmin(BaseModelAdminMixin, admin.ModelAdmin):
|
||||
"""Admin conf for Rating Strategy model."""
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from pprint import pprint
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.db.models import Q
|
||||
|
||||
|
|
@ -19,8 +17,6 @@ class Command(BaseCommand):
|
|||
Q(mark__isnull=True)
|
||||
).filter(aasm_state='published').values_list('establishment_id', 'mark', 'updated_at')
|
||||
|
||||
print(queryset.count())
|
||||
|
||||
for es_id, new_mark, new_date in queryset:
|
||||
try:
|
||||
mark, date = valid_data[es_id]
|
||||
|
|
@ -41,6 +37,5 @@ class Command(BaseCommand):
|
|||
establishment.public_mark = int(value[0])
|
||||
establishment.save()
|
||||
count += 1
|
||||
break
|
||||
|
||||
self.stdout.write(self.style.WARNING(f'Updated {count} objects.'))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
"""Run recalculating toque number for establishments."""
|
||||
from django.core.management.base import BaseCommand
|
||||
from establishment.models import Establishment
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
|
||||
help = 'Recalculation toque number for all establishments.'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
for establishment in Establishment.objects.select_related('address__city__country'):
|
||||
print(f'Recalculate for {establishment.name} ({establishment.id})')
|
||||
establishment.recalculate_toque_number()
|
||||
33
apps/establishment/migrations/0048_ratingstrategy.py
Normal file
33
apps/establishment/migrations/0048_ratingstrategy.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# Generated by Django 2.2.4 on 2019-10-31 15:55
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('location', '0020_merge_20191030_1714'),
|
||||
('establishment', '0047_merge_20191030_1714'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='RatingStrategy',
|
||||
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')),
|
||||
('toque_number', models.IntegerField(choices=[(1, 'One'), (2, 'Two'), (3, 'Three'), (4, 'Four'), (5, 'Five')])),
|
||||
('public_mark_min_value', models.IntegerField()),
|
||||
('public_mark_max_value', models.IntegerField()),
|
||||
('country', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='location.Country', verbose_name='Country')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Rating strategy',
|
||||
'verbose_name_plural': 'Rating strategy',
|
||||
'unique_together': {('country', 'toque_number')},
|
||||
},
|
||||
),
|
||||
]
|
||||
19
apps/establishment/migrations/0049_auto_20191031_1616.py
Normal file
19
apps/establishment/migrations/0049_auto_20191031_1616.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# Generated by Django 2.2.4 on 2019-10-31 16:16
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('establishment', '0048_ratingstrategy'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='ratingstrategy',
|
||||
name='country',
|
||||
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='location.Country', verbose_name='Country'),
|
||||
),
|
||||
]
|
||||
|
|
@ -14,7 +14,6 @@ from django.db.models import When, Case, F, ExpressionWrapper, Subquery, Q
|
|||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from phonenumber_field.modelfields import PhoneNumberField
|
||||
from pytz import timezone as ptz
|
||||
from timezone_field import TimeZoneField
|
||||
|
||||
from collection.models import Collection
|
||||
|
|
@ -384,7 +383,13 @@ class Establishment(ProjectBaseMixin, URLImageMixin, TranslatedFieldsMixin):
|
|||
|
||||
# todo: recalculate toque_number
|
||||
def recalculate_toque_number(self):
|
||||
self.toque_number = 4
|
||||
toque_number = None
|
||||
if self.address and self.public_mark:
|
||||
toque_number = RatingStrategy.objects. \
|
||||
get_toque_number(country=self.address.city.country,
|
||||
public_mark=self.public_mark)
|
||||
self.toque_number = toque_number
|
||||
self.save()
|
||||
|
||||
def recalculate_price_level(self, low_price=None, high_price=None):
|
||||
if low_price is None or high_price is None:
|
||||
|
|
@ -669,3 +674,62 @@ class SocialNetwork(models.Model):
|
|||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
|
||||
class RatingStrategyManager(models.Manager):
|
||||
"""Extended manager for RatingStrategy."""
|
||||
|
||||
def get_toque_number(self, country, public_mark):
|
||||
"""Get toque number for country and public_mark."""
|
||||
qs = self.model.objects.by_country(country)
|
||||
if not qs.exists():
|
||||
qs = self.model.objects.by_country(None)
|
||||
obj = qs.for_public_mark(public_mark).first()
|
||||
if obj:
|
||||
return obj.toque_number
|
||||
return None
|
||||
|
||||
|
||||
class RatingStrategyQuerySet(models.QuerySet):
|
||||
"""Extended queryset for RatingStrategy."""
|
||||
|
||||
def by_country(self, country):
|
||||
"""Filter by country."""
|
||||
return self.filter(country=country)
|
||||
|
||||
def for_public_mark(self, public_mark):
|
||||
"""Filter for value."""
|
||||
return self.filter(public_mark_min_value__lte=public_mark,
|
||||
public_mark_max_value__gte=public_mark)
|
||||
|
||||
|
||||
class RatingStrategy(ProjectBaseMixin):
|
||||
"""Rating Strategy model."""
|
||||
|
||||
TOQUE_NUMBER_CHOICES = (
|
||||
(1, _('One')),
|
||||
(2, _('Two')),
|
||||
(3, _('Three')),
|
||||
(4, _('Four')),
|
||||
(5, _('Five')),
|
||||
)
|
||||
|
||||
country = models.ForeignKey('location.Country', null=True, blank=True,
|
||||
default=None, on_delete=models.CASCADE,
|
||||
verbose_name=_('Country'))
|
||||
toque_number = models.IntegerField(choices=TOQUE_NUMBER_CHOICES)
|
||||
public_mark_min_value = models.IntegerField()
|
||||
public_mark_max_value = models.IntegerField()
|
||||
|
||||
objects = RatingStrategyManager.from_queryset(RatingStrategyQuerySet)()
|
||||
|
||||
class Meta:
|
||||
"""Meta class."""
|
||||
|
||||
verbose_name = _('Rating strategy')
|
||||
verbose_name_plural = _('Rating strategy')
|
||||
unique_together = ('country', 'toque_number')
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.country.code if self.country else "Other country"}. ' \
|
||||
f'"{self.toque_number}": {self.public_mark_min_value}-' \
|
||||
f'{self.public_mark_max_value}'
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
from django.db.models import Q, QuerySet
|
||||
|
||||
from transfer.serializers.location import CountrySerializer, RegionSerializer, CitySerializer, AddressSerializer
|
||||
from transfer.serializers.location import CountrySerializer, RegionSerializer, \
|
||||
CitySerializer, AddressSerializer, \
|
||||
Country
|
||||
from transfer.models import Cities, Locations
|
||||
from pprint import pprint
|
||||
|
||||
|
|
@ -131,6 +133,13 @@ def transfer_addresses():
|
|||
pprint(f"Address serializer errors: {serialized_data.errors}")
|
||||
|
||||
|
||||
def update_flags():
|
||||
queryset = Country.objects.only("id", "code", "svg_image").filter(old_id__isnull=False)
|
||||
|
||||
for query in queryset:
|
||||
query.svg_image = f"/image/image/10-31-2019/{query.code}.svg"
|
||||
query.save()
|
||||
|
||||
|
||||
data_types = {
|
||||
"dictionaries": [
|
||||
|
|
@ -138,5 +147,8 @@ data_types = {
|
|||
transfer_regions,
|
||||
transfer_cities,
|
||||
transfer_addresses
|
||||
],
|
||||
"update_country_flag": [
|
||||
update_flags
|
||||
]
|
||||
}
|
||||
|
|
|
|||
48
apps/main/migrations/0024_auto_20191031_1439.py
Normal file
48
apps/main/migrations/0024_auto_20191031_1439.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
# Generated by Django 2.2.4 on 2019-10-31 14:39
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('main', '0023_merge_20191028_0725'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='carousel',
|
||||
name='active',
|
||||
field=models.BooleanField(default=False, verbose_name='old active'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='carousel',
|
||||
name='attachment_suffix_url',
|
||||
field=models.TextField(blank=True, default=None, null=True, verbose_name='old attachment_suffix_url'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='carousel',
|
||||
name='description',
|
||||
field=models.CharField(blank=True, default=None, max_length=255, null=True, verbose_name='old description'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='carousel',
|
||||
name='link',
|
||||
field=models.CharField(blank=True, default=None, max_length=255, null=True, verbose_name='old link'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='carousel',
|
||||
name='link_title',
|
||||
field=models.CharField(blank=True, default=None, max_length=255, null=True, verbose_name='old link_title'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='carousel',
|
||||
name='old_id',
|
||||
field=models.PositiveIntegerField(blank=True, default=None, null=True, verbose_name='old id'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='carousel',
|
||||
name='title',
|
||||
field=models.CharField(blank=True, default=None, max_length=255, null=True, verbose_name='old title'),
|
||||
),
|
||||
]
|
||||
18
apps/main/migrations/0025_carousel_is_parse.py
Normal file
18
apps/main/migrations/0025_carousel_is_parse.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 2.2.4 on 2019-10-31 15:30
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('main', '0024_auto_20191031_1439'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='carousel',
|
||||
name='is_parse',
|
||||
field=models.BooleanField(default=False, verbose_name='is parse'),
|
||||
),
|
||||
]
|
||||
24
apps/main/migrations/0026_auto_20191101_0500.py
Normal file
24
apps/main/migrations/0026_auto_20191101_0500.py
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# Generated by Django 2.2.4 on 2019-11-01 05:00
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('main', '0025_carousel_is_parse'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='carousel',
|
||||
name='content_type',
|
||||
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='carousel',
|
||||
name='object_id',
|
||||
field=models.PositiveIntegerField(blank=True, default=None, null=True),
|
||||
),
|
||||
]
|
||||
|
|
@ -130,7 +130,6 @@ class SiteSettingsQuerySet(models.QuerySet):
|
|||
|
||||
|
||||
class SiteSettings(ProjectBaseMixin):
|
||||
|
||||
subdomain = models.CharField(max_length=255, db_index=True, unique=True,
|
||||
verbose_name=_('Subdomain'))
|
||||
country = models.OneToOneField(Country, on_delete=models.PROTECT,
|
||||
|
|
@ -172,8 +171,9 @@ class SiteSettings(ProjectBaseMixin):
|
|||
|
||||
@property
|
||||
def published_sitefeatures(self):
|
||||
return self.sitefeature_set\
|
||||
.filter(Q(published=True) and Q(feature__source__in=[PlatformMixin.WEB, PlatformMixin.ALL]))
|
||||
return self.sitefeature_set. \
|
||||
filter(Q(published=True) &
|
||||
Q(feature__source__in=[PlatformMixin.WEB, PlatformMixin.ALL]))
|
||||
|
||||
@property
|
||||
def site_url(self):
|
||||
|
|
@ -281,10 +281,19 @@ class CarouselQuerySet(models.QuerySet):
|
|||
|
||||
class Carousel(models.Model):
|
||||
"""Carousel model."""
|
||||
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
|
||||
object_id = models.PositiveIntegerField()
|
||||
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE, blank=True, null=True, default=None)
|
||||
object_id = models.PositiveIntegerField(blank=True, null=True, default=None)
|
||||
content_object = generic.GenericForeignKey('content_type', 'object_id')
|
||||
|
||||
old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None)
|
||||
title = models.CharField(_('old title'), max_length=255, blank=True, null=True, default=None)
|
||||
link = models.CharField(_('old link'), max_length=255, blank=True, null=True, default=None)
|
||||
attachment_suffix_url = models.TextField(_('old attachment_suffix_url'), blank=True, null=True, default=None)
|
||||
description = models.CharField(_('old description'), max_length=255, blank=True, null=True, default=None)
|
||||
link_title = models.CharField(_('old link_title'), max_length=255, blank=True, null=True, default=None)
|
||||
active = models.BooleanField(_('old active'), default=False)
|
||||
is_parse = models.BooleanField(_('is parse'), default=False)
|
||||
|
||||
objects = CarouselQuerySet.as_manager()
|
||||
|
||||
class Meta:
|
||||
|
|
|
|||
|
|
@ -71,7 +71,8 @@ card = {
|
|||
"facebook_page_url": "facebook_page_url",
|
||||
"instagram_page_url": "instagram_page_url",
|
||||
"contact_email": "contact_email",
|
||||
"config": ("config", "django.db.models.JSONField") #TODO в качесте ключа использовать country_code_2 из legacy - ?
|
||||
"config": ("config", "django.db.models.JSONField")
|
||||
# TODO в качесте ключа использовать country_code_2 из legacy - ?
|
||||
},
|
||||
# "relations": {
|
||||
# # Как работать c отношение OneToOneField
|
||||
|
|
@ -133,7 +134,7 @@ card = {
|
|||
"vintage_year": "year",
|
||||
}
|
||||
},
|
||||
#TODO вопрос с content_type
|
||||
# TODO вопрос с content_type
|
||||
"relations": {
|
||||
"AwardTypes": [(
|
||||
("award_type", None),
|
||||
|
|
@ -143,4 +144,4 @@ card = {
|
|||
}
|
||||
}
|
||||
|
||||
used_apps = ("locations", )
|
||||
used_apps = ("locations",)
|
||||
|
|
|
|||
19
apps/main/transfer_data.py
Normal file
19
apps/main/transfer_data.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
from pprint import pprint
|
||||
|
||||
from transfer.models import CarouselElements
|
||||
from transfer.serializers.carousel import CarouselSerializer
|
||||
|
||||
|
||||
def transfer_carousel():
|
||||
queryset = CarouselElements.objects.all()
|
||||
|
||||
serialized_data = CarouselSerializer(data=list(queryset.values()), many=True)
|
||||
if serialized_data.is_valid():
|
||||
serialized_data.save()
|
||||
else:
|
||||
pprint(f'Carousel serializer errors: {serialized_data.errors}')
|
||||
|
||||
|
||||
data_types = {
|
||||
'whirligig': [transfer_carousel]
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ class EstablishmentDocument(Document):
|
|||
works_noon = fields.ListField(fields.IntegerField(
|
||||
attr='works_noon'
|
||||
))
|
||||
# works_now = fields.BooleanField(attr='works_now')
|
||||
works_now = fields.BooleanField(attr='works_now')
|
||||
tags = fields.ObjectField(
|
||||
properties={
|
||||
'id': fields.IntegerField(attr='id'),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"""Search indexes filters."""
|
||||
from elasticsearch_dsl.query import Q
|
||||
from django_elasticsearch_dsl_drf.filter_backends import SearchFilterBackend
|
||||
from utils.models import get_current_language
|
||||
from utils.models import get_current_locale
|
||||
|
||||
|
||||
class CustomSearchFilterBackend(SearchFilterBackend):
|
||||
|
|
@ -12,7 +12,7 @@ class CustomSearchFilterBackend(SearchFilterBackend):
|
|||
field_name = field
|
||||
if hasattr(view, 'search_fields') and hasattr(view, 'translated_search_fields'):
|
||||
if field in view.translated_search_fields:
|
||||
field_name = f'{field}.{get_current_language()}'
|
||||
field_name = f'{field}.{get_current_locale()}'
|
||||
return field_name
|
||||
|
||||
def construct_search(self, request, view):
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"""Search indexes utils."""
|
||||
from django_elasticsearch_dsl import fields
|
||||
from utils.models import get_current_language
|
||||
from utils.models import get_current_locale, get_default_locale
|
||||
|
||||
|
||||
# object field properties
|
||||
|
|
@ -19,4 +19,8 @@ def get_translated_value(value):
|
|||
field_dict = value.to_dict()
|
||||
elif isinstance(value, dict):
|
||||
field_dict = value
|
||||
return field_dict.get(get_current_language())
|
||||
value = field_dict.get(get_current_locale())
|
||||
# fallback
|
||||
if value is None:
|
||||
value = field_dict.get(get_default_locale())
|
||||
return value
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ class EstablishmentDocumentViewSet(BaseDocumentViewSet):
|
|||
'lookups': [
|
||||
constants.LOOKUP_QUERY_IN,
|
||||
],
|
||||
},
|
||||
},
|
||||
'works_noon': {
|
||||
'field': 'works_noon',
|
||||
'lookups': [
|
||||
|
|
@ -152,12 +152,12 @@ class EstablishmentDocumentViewSet(BaseDocumentViewSet):
|
|||
constants.LOOKUP_QUERY_IN,
|
||||
],
|
||||
},
|
||||
# 'works_now': {
|
||||
# 'field': 'works_now',
|
||||
# 'lookups': [
|
||||
# constants.LOOKUP_FILTER_TERM,
|
||||
# ]
|
||||
# },
|
||||
'works_now': {
|
||||
'field': 'works_now',
|
||||
'lookups': [
|
||||
constants.LOOKUP_FILTER_TERM,
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
geo_spatial_filter_fields = {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ class TagBaseSerializer(serializers.ModelSerializer):
|
|||
|
||||
# todo: refactor this
|
||||
# label_translated = TranslatedField()
|
||||
label_translated = serializers.CharField(source='value')
|
||||
label_translated = serializers.CharField(source='value', read_only=True, allow_null=True)
|
||||
index_name = serializers.CharField(source='value', read_only=True, allow_null=True)
|
||||
|
||||
class Meta:
|
||||
"""Meta class."""
|
||||
|
|
@ -23,6 +24,7 @@ class TagBaseSerializer(serializers.ModelSerializer):
|
|||
fields = (
|
||||
'id',
|
||||
'label_translated',
|
||||
'index_name',
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -43,7 +45,7 @@ class TagCategoryBaseSerializer(serializers.ModelSerializer):
|
|||
|
||||
# todo: refactor this
|
||||
# label_translated = TranslatedField()
|
||||
label_translated = serializers.CharField(source='index_name')
|
||||
label_translated = serializers.CharField(source='index_name', read_only=True, allow_null=True)
|
||||
tags = TagBaseSerializer(many=True, read_only=True)
|
||||
|
||||
class Meta:
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ class Command(BaseCommand):
|
|||
"""Типы данных для трансфера
|
||||
ВНИМАНИЕ: первые буквы типов данных должны быть уникальны!
|
||||
"""
|
||||
DATA_TYPES = [
|
||||
SHORT_DATA_TYPES = [
|
||||
'dictionaries',
|
||||
'news',
|
||||
'account',
|
||||
|
|
@ -21,20 +21,40 @@ class Command(BaseCommand):
|
|||
'overlook',
|
||||
'tmp',
|
||||
'menu',
|
||||
'location_establishment'
|
||||
'location_establishment',
|
||||
'whirligig',
|
||||
]
|
||||
|
||||
LONG_DATA_TYPES = [
|
||||
'update_country_flag'
|
||||
]
|
||||
|
||||
def handle(self, *args, **options):
|
||||
"""Находим включённую опцию путём пересечения множества типов данных и множества включённых опций"""
|
||||
data_type = list(set(option for option in options.keys() if options[option]) & set(self.DATA_TYPES))
|
||||
data_type = list(set(option for option in options.keys() if options[option]) & set(self.LONG_DATA_TYPES))
|
||||
if len(data_type) != 1:
|
||||
print("You must set correct option!\r\nYou can get options list with \r\n\r\n\tmanage.py help transfer\r\n")
|
||||
exit(1)
|
||||
transfer_objects(data_type[0])
|
||||
data_type = list(set(option for option in options.keys() if options[option]) & set(self.SHORT_DATA_TYPES))
|
||||
if len(data_type) != 1:
|
||||
print("You must set correct option!\r\nYou can get options list with \r\n\r\n\tmanage.py help transfer\r\n")
|
||||
exit(1)
|
||||
else:
|
||||
data_type = data_type[0]
|
||||
else:
|
||||
data_type = data_type[0]
|
||||
|
||||
transfer_objects(data_type)
|
||||
|
||||
def add_arguments(self, parser):
|
||||
for option_type in self.LONG_DATA_TYPES:
|
||||
parser.add_argument(
|
||||
f'--{option_type}',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=f'Transfer {option_type} objects'
|
||||
)
|
||||
|
||||
"""Добавляем опции к команде, основываясь на типах данных, определённых в DATA_TYPES"""
|
||||
for option_type in self.DATA_TYPES:
|
||||
for option_type in self.SHORT_DATA_TYPES:
|
||||
parser.add_argument(
|
||||
f'-{option_type[:1]}',
|
||||
f'--{option_type}',
|
||||
|
|
|
|||
|
|
@ -938,3 +938,25 @@ class KeyValueMetadatumKeyValueMetadatumEstablishments(MigrateMixin):
|
|||
# class Meta:
|
||||
# managed = False
|
||||
# db_table = 'wine_types'
|
||||
|
||||
class CarouselElements(MigrateMixin):
|
||||
using = 'legacy'
|
||||
|
||||
title = models.CharField(max_length=255, blank=True, null=True)
|
||||
link = models.CharField(max_length=255, blank=True, null=True)
|
||||
home_page_id = models.IntegerField(blank=True, null=True)
|
||||
created_at = models.DateTimeField()
|
||||
updated_at = models.DateTimeField()
|
||||
attachment_file_name = models.CharField(max_length=255, blank=True, null=True)
|
||||
attachment_content_type = models.CharField(max_length=255, blank=True, null=True)
|
||||
attachment_file_size = models.IntegerField(blank=True, null=True)
|
||||
attachment_updated_at = models.DateTimeField(blank=True, null=True)
|
||||
attachment_suffix_url = models.TextField(blank=True, null=True)
|
||||
geometries = models.CharField(max_length=1024, blank=True, null=True)
|
||||
active = models.IntegerField(blank=True, null=True)
|
||||
description = models.CharField(max_length=255, blank=True, null=True)
|
||||
link_title = models.CharField(max_length=255, blank=True, null=True)
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'carousel_elements'
|
||||
|
|
|
|||
59
apps/transfer/serializers/carousel.py
Normal file
59
apps/transfer/serializers/carousel.py
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
from django.contrib.contenttypes.models import ContentType
|
||||
from rest_framework import serializers
|
||||
|
||||
from establishment.models import Establishment
|
||||
from main.models import Carousel
|
||||
from news.models import News
|
||||
|
||||
|
||||
def get_obj_data(model, slug):
|
||||
try:
|
||||
obj = model.objects.get(slug=slug)
|
||||
except model.DoesNotExist:
|
||||
return None, None
|
||||
else:
|
||||
content_type = ContentType.objects.get_for_model(obj)
|
||||
return obj.id, content_type.id
|
||||
|
||||
|
||||
class CarouselSerializer(serializers.Serializer):
|
||||
id = serializers.IntegerField()
|
||||
title = serializers.CharField(allow_null=True, allow_blank=True)
|
||||
link = serializers.CharField(allow_null=True)
|
||||
link_title = serializers.CharField(allow_null=True, allow_blank=True)
|
||||
description = serializers.CharField(allow_null=True, allow_blank=True)
|
||||
attachment_suffix_url = serializers.CharField(allow_null=True)
|
||||
active = serializers.IntegerField()
|
||||
|
||||
def create(self, validated_data):
|
||||
object_id, content_type_id = self.get_content_type(validated_data)
|
||||
validated_data.update({
|
||||
'active': bool(int(validated_data['active'])),
|
||||
'content_type_id': content_type_id,
|
||||
'object_id': object_id,
|
||||
'is_parse': bool(object_id),
|
||||
})
|
||||
obj = Carousel.objects.create(**validated_data)
|
||||
return obj
|
||||
|
||||
@staticmethod
|
||||
def get_content_type(data):
|
||||
link = data['link']
|
||||
if not link:
|
||||
return None
|
||||
|
||||
obj_data = None, None
|
||||
site = 'gaultmillau.com'
|
||||
if site in link:
|
||||
data = link.split('/')
|
||||
|
||||
try:
|
||||
_type = data[3]
|
||||
except IndexError:
|
||||
pass
|
||||
else:
|
||||
if _type in ('news', 'pages'):
|
||||
obj_data = get_obj_data(News, data[4])
|
||||
elif _type == 'restaurant':
|
||||
obj_data = get_obj_data(Establishment, data[4])
|
||||
return obj_data
|
||||
|
|
@ -6,8 +6,8 @@ from establishment.models import Establishment, ContactEmail, ContactPhone, Esta
|
|||
from location.models import Address
|
||||
from timetable.models import Timetable
|
||||
from utils.legacy_parser import parse_legacy_schedule_content
|
||||
from utils.serializers import TimeZoneChoiceField
|
||||
from utils.slug_generator import generate_unique_slug
|
||||
from pytz import timezone as ptz
|
||||
|
||||
|
||||
class EstablishmentSerializer(serializers.ModelSerializer):
|
||||
|
|
@ -26,7 +26,7 @@ class EstablishmentSerializer(serializers.ModelSerializer):
|
|||
twitter = serializers.CharField(allow_null=True, allow_blank=True)
|
||||
booking = serializers.CharField(allow_null=True, allow_blank=True)
|
||||
state = serializers.CharField(allow_null=True)
|
||||
tz = serializers.CharField()
|
||||
tz = TimeZoneChoiceField()
|
||||
created = serializers.DateTimeField(format='%m-%d-%Y %H:%M:%S')
|
||||
|
||||
class Meta:
|
||||
|
|
@ -59,7 +59,6 @@ class EstablishmentSerializer(serializers.ModelSerializer):
|
|||
'establishment_type_id': self.get_type(data),
|
||||
'is_publish': data.get('state') == 'published',
|
||||
})
|
||||
data['tz'] = ptz(data['tz'])
|
||||
data.pop('location')
|
||||
data.pop('type')
|
||||
data.pop('state')
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ def transfer_objects(data_type):
|
|||
for app in apps.get_app_configs():
|
||||
if exists(f"{app.path}/transfer_data.py"):
|
||||
card_module = SourceFileLoader("transfer", f"{app.path}/transfer_data.py").load_module()
|
||||
if not hasattr(card_module, "data_types") or not isinstance(card_module.data_types, dict) or len(card_module.data_types) < 1:
|
||||
if not hasattr(card_module, "data_types") \
|
||||
or not isinstance(card_module.data_types, dict) \
|
||||
or len(card_module.data_types) < 1:
|
||||
continue
|
||||
|
||||
for module_data_type, transfer_funcs in card_module.data_types.items():
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ from django.contrib.postgres.fields.jsonb import KeyTextTransform
|
|||
from django.utils import timezone
|
||||
from django.utils.html import mark_safe
|
||||
from django.utils.translation import ugettext_lazy as _, get_language
|
||||
from configuration.models import TranslationSettings
|
||||
from easy_thumbnails.fields import ThumbnailerImageField
|
||||
from sorl.thumbnail import get_thumbnail
|
||||
from sorl.thumbnail.fields import ImageField as SORLImageField
|
||||
|
|
@ -59,13 +60,26 @@ def to_locale(language):
|
|||
return language + '-' + country
|
||||
|
||||
|
||||
def get_current_locale():
|
||||
"""Get current language."""
|
||||
return to_locale(get_language())
|
||||
|
||||
|
||||
def get_default_locale():
|
||||
return TranslationSettings.get_solo().default_language or \
|
||||
settings.FALLBACK_LOCALE
|
||||
|
||||
|
||||
def translate_field(self, field_name):
|
||||
def translate(self):
|
||||
field = getattr(self, field_name)
|
||||
if isinstance(field, dict):
|
||||
return field.get(to_locale(get_language()))
|
||||
value = field.get(to_locale(get_language()))
|
||||
# fallback
|
||||
if value is None:
|
||||
value = field.get(get_default_locale())
|
||||
return value
|
||||
return None
|
||||
|
||||
return translate
|
||||
|
||||
|
||||
|
|
@ -111,15 +125,10 @@ class TranslatedFieldsMixin:
|
|||
if self.STR_FIELD_NAME:
|
||||
field = getattr(self, getattr(self, 'STR_FIELD_NAME'))
|
||||
if isinstance(field, dict):
|
||||
value = field.get(get_current_language())
|
||||
value = field.get(get_current_locale())
|
||||
return value if value else super(TranslatedFieldsMixin, self).__str__()
|
||||
|
||||
|
||||
def get_current_language():
|
||||
"""Get current language."""
|
||||
return to_locale(get_language())
|
||||
|
||||
|
||||
class OAuthProjectMixin:
|
||||
"""OAuth2 mixin for project GM"""
|
||||
|
||||
|
|
|
|||
|
|
@ -159,9 +159,9 @@ DATABASES = {
|
|||
},
|
||||
'legacy': {
|
||||
'ENGINE': 'django.db.backends.mysql',
|
||||
'HOST': '172.17.0.1',
|
||||
# 'HOST': '172.17.0.1',
|
||||
# 'HOST': '172.23.0.1',
|
||||
# 'HOST': 'mysql_db',
|
||||
'HOST': 'mysql_db',
|
||||
'PORT': 3306,
|
||||
'NAME': 'dev',
|
||||
'USER': 'dev',
|
||||
|
|
@ -488,3 +488,5 @@ MEDIA_LOCATION = 'media'
|
|||
|
||||
PHONENUMBER_DB_FORMAT = 'NATIONAL'
|
||||
PHONENUMBER_DEFAULT_REGION = "FR"
|
||||
|
||||
FALLBACK_LOCALE = 'en-GB'
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user