Merge branch 'develop' into feature/gm-148

This commit is contained in:
evgeniy-st 2019-10-22 17:11:22 +03:00
commit 0c8959f4e7
14 changed files with 123 additions and 86 deletions

View File

@ -0,0 +1,23 @@
# Generated by Django 2.2.4 on 2019-10-22 12:42
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('collection', '0013_collection_slug'),
]
operations = [
migrations.AlterField(
model_name='collection',
name='end',
field=models.DateTimeField(blank=True, default=None, null=True, verbose_name='end'),
),
migrations.AlterField(
model_name='guide',
name='end',
field=models.DateTimeField(blank=True, default=None, null=True, verbose_name='end'),
),
]

View File

@ -1,13 +1,11 @@
from django.contrib.postgres.fields import JSONField
from django.contrib.contenttypes.fields import ContentType from django.contrib.contenttypes.fields import ContentType
from django.contrib.postgres.fields import JSONField
from utils.models import TJSONField
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from utils.models import ProjectBaseMixin, URLImageMixin from utils.models import ProjectBaseMixin, URLImageMixin
from utils.models import TJSONField
from utils.models import TranslatedFieldsMixin from utils.models import TranslatedFieldsMixin
from utils.querysets import RelatedObjectsCountMixin from utils.querysets import RelatedObjectsCountMixin
@ -24,7 +22,8 @@ class CollectionNameMixin(models.Model):
class CollectionDateMixin(models.Model): class CollectionDateMixin(models.Model):
"""CollectionDate mixin""" """CollectionDate mixin"""
start = models.DateTimeField(_('start')) start = models.DateTimeField(_('start'))
end = models.DateTimeField(_('end')) end = models.DateTimeField(blank=True, null=True, default=None,
verbose_name=_('end'))
class Meta: class Meta:
"""Meta class""" """Meta class"""

View File

@ -1,6 +1,7 @@
"""Establishment app filters.""" """Establishment app filters."""
from django.core.validators import EMPTY_VALUES from django.core.validators import EMPTY_VALUES
from django_filters import rest_framework as filters from django_filters import rest_framework as filters
from establishment import models from establishment import models
@ -10,10 +11,10 @@ class EstablishmentFilter(filters.FilterSet):
tag_id = filters.NumberFilter(field_name='tags__metadata__id',) tag_id = filters.NumberFilter(field_name='tags__metadata__id',)
award_id = filters.NumberFilter(field_name='awards__id',) award_id = filters.NumberFilter(field_name='awards__id',)
search = filters.CharFilter(method='search_text') search = filters.CharFilter(method='search_text')
est_type = filters.ChoiceFilter(choices=models.EstablishmentType.INDEX_NAME_TYPES, type = filters.ChoiceFilter(choices=models.EstablishmentType.INDEX_NAME_TYPES,
method='by_type') method='by_type')
est_subtype = filters.ChoiceFilter(choices=models.EstablishmentSubType.INDEX_NAME_TYPES, subtype = filters.ChoiceFilter(choices=models.EstablishmentSubType.INDEX_NAME_TYPES,
method='by_subtype') method='by_subtype')
class Meta: class Meta:
"""Meta class.""" """Meta class."""
@ -23,8 +24,8 @@ class EstablishmentFilter(filters.FilterSet):
'tag_id', 'tag_id',
'award_id', 'award_id',
'search', 'search',
'est_type', 'type',
'est_subtype', 'subtype',
) )
def search_text(self, queryset, name, value): def search_text(self, queryset, name, value):
@ -34,10 +35,14 @@ class EstablishmentFilter(filters.FilterSet):
return queryset return queryset
def by_type(self, queryset, name, value): def by_type(self, queryset, name, value):
return queryset.by_type(value) if value not in EMPTY_VALUES:
return queryset.by_type(value)
return queryset
def by_subtype(self, queryset, name, value): def by_subtype(self, queryset, name, value):
return queryset.by_subtype(value) if value not in EMPTY_VALUES:
return queryset.by_subtype(value)
return queryset
class EstablishmentTypeTagFilter(filters.FilterSet): class EstablishmentTypeTagFilter(filters.FilterSet):

View File

@ -0,0 +1,19 @@
# Generated by Django 2.2.4 on 2019-10-22 13:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('tag', '0004_tag_priority'),
('establishment', '0039_establishmentsubtype_index_name'),
]
operations = [
migrations.AddField(
model_name='employee',
name='tags',
field=models.ManyToManyField(related_name='employees', to='tag.Tag', verbose_name='Tags'),
),
]

View File

@ -356,11 +356,8 @@ class Establishment(ProjectBaseMixin, URLImageMixin, TranslatedFieldsMixin):
verbose_name=_('Establishment slug'), editable=True) verbose_name=_('Establishment slug'), editable=True)
awards = generic.GenericRelation(to='main.Award', related_query_name='establishment') awards = generic.GenericRelation(to='main.Award', related_query_name='establishment')
# todo: remove after data merge
# tags = generic.GenericRelation(to='main.MetaDataContent')
tags = models.ManyToManyField('tag.Tag', related_name='establishments', tags = models.ManyToManyField('tag.Tag', related_name='establishments',
verbose_name=_('Tag')) verbose_name=_('Tag'))
old_tags = generic.GenericRelation(to='main.MetaDataContent')
reviews = generic.GenericRelation(to='review.Review') reviews = generic.GenericRelation(to='review.Review')
comments = generic.GenericRelation(to='comment.Comment') comments = generic.GenericRelation(to='comment.Comment')
favorites = generic.GenericRelation(to='favorites.Favorites') favorites = generic.GenericRelation(to='favorites.Favorites')
@ -535,7 +532,8 @@ class Employee(BaseAttributes):
establishments = models.ManyToManyField(Establishment, related_name='employees', establishments = models.ManyToManyField(Establishment, related_name='employees',
through=EstablishmentEmployee,) through=EstablishmentEmployee,)
awards = generic.GenericRelation(to='main.Award', related_query_name='employees') awards = generic.GenericRelation(to='main.Award', related_query_name='employees')
tags = generic.GenericRelation(to='main.MetaDataContent') tags = models.ManyToManyField('tag.Tag', related_name='employees',
verbose_name=_('Tags'))
class Meta: class Meta:
"""Meta class.""" """Meta class."""

View File

@ -8,10 +8,10 @@ from comment import models as comment_models
from establishment import filters from establishment import filters
from establishment import models, serializers from establishment import models, serializers
from main import methods from main import methods
from main.models import MetaDataContent
from utils.pagination import EstablishmentPortionPagination from utils.pagination import EstablishmentPortionPagination
from utils.permissions import IsCountryAdmin from utils.permissions import IsCountryAdmin
class EstablishmentMixinView: class EstablishmentMixinView:
"""Establishment mixin.""" """Establishment mixin."""

View File

@ -55,6 +55,14 @@ class Region(models.Model):
return self.name return self.name
class CityQuerySet(models.QuerySet):
"""Extended queryset for City model."""
def by_country_code(self, code):
"""Return establishments by country code"""
return self.filter(country__code=code)
class City(models.Model): class City(models.Model):
"""Region model.""" """Region model."""
@ -70,6 +78,8 @@ class City(models.Model):
is_island = models.BooleanField(_('is island'), default=False) is_island = models.BooleanField(_('is island'), default=False)
objects = CityQuerySet.as_manager()
class Meta: class Meta:
verbose_name_plural = _('cities') verbose_name_plural = _('cities')
verbose_name = _('city') verbose_name = _('city')
@ -79,7 +89,6 @@ class City(models.Model):
class Address(models.Model): class Address(models.Model):
"""Address model.""" """Address model."""
city = models.ForeignKey(City, verbose_name=_('city'), on_delete=models.CASCADE) city = models.ForeignKey(City, verbose_name=_('city'), on_delete=models.CASCADE)
street_name_1 = models.CharField( street_name_1 = models.CharField(

View File

@ -1,7 +1,6 @@
"""Location app mobile urlconf.""" """Location app mobile urlconf."""
from location.urls.common import urlpatterns as common_urlpatterns from location.urls.common import urlpatterns as common_urlpatterns
urlpatterns = [] urlpatterns = []
urlpatterns.extend(common_urlpatterns) urlpatterns.extend(common_urlpatterns)

View File

@ -10,7 +10,7 @@ class CountryViewMixin(generics.GenericAPIView):
"""View Mixin for model Country""" """View Mixin for model Country"""
serializer_class = serializers.CountrySerializer serializer_class = serializers.CountrySerializer
permission_classes = (permissions.AllowAny, ) permission_classes = (permissions.AllowAny,)
queryset = models.Country.objects.all() queryset = models.Country.objects.all()
@ -56,7 +56,7 @@ class RegionRetrieveView(RegionViewMixin, generics.RetrieveAPIView):
class RegionListView(RegionViewMixin, generics.ListAPIView): class RegionListView(RegionViewMixin, generics.ListAPIView):
"""List view for model Country""" """List view for model Country"""
permission_classes = (permissions.AllowAny, ) permission_classes = (permissions.AllowAny,)
serializer_class = serializers.CountrySerializer serializer_class = serializers.CountrySerializer
@ -83,9 +83,15 @@ class CityRetrieveView(CityViewMixin, generics.RetrieveAPIView):
class CityListView(CityViewMixin, generics.ListAPIView): class CityListView(CityViewMixin, generics.ListAPIView):
"""List view for model City""" """List view for model City"""
permission_classes = (permissions.AllowAny, ) permission_classes = (permissions.AllowAny,)
serializer_class = serializers.CitySerializer serializer_class = serializers.CitySerializer
def get_queryset(self):
qs = super().get_queryset()
if self.request.country_code:
qs = qs.by_country_code(self.request.country_code)
return qs
class CityDestroyView(CityViewMixin, generics.DestroyAPIView): class CityDestroyView(CityViewMixin, generics.DestroyAPIView):
"""Destroy view for model City""" """Destroy view for model City"""
@ -110,7 +116,5 @@ class AddressRetrieveView(AddressViewMixin, generics.RetrieveAPIView):
class AddressListView(AddressViewMixin, generics.ListAPIView): class AddressListView(AddressViewMixin, generics.ListAPIView):
"""List view for model Address""" """List view for model Address"""
permission_classes = (permissions.AllowAny, ) permission_classes = (permissions.AllowAny,)
serializer_class = serializers.AddressDetailSerializer serializer_class = serializers.AddressDetailSerializer

View File

@ -0,0 +1,38 @@
# Generated by Django 2.2.4 on 2019-10-22 13:59
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('main', '0018_feature_source'),
]
operations = [
migrations.RemoveField(
model_name='metadatacategory',
name='content_type',
),
migrations.RemoveField(
model_name='metadatacategory',
name='country',
),
migrations.RemoveField(
model_name='metadatacontent',
name='content_type',
),
migrations.RemoveField(
model_name='metadatacontent',
name='metadata',
),
migrations.DeleteModel(
name='MetaData',
),
migrations.DeleteModel(
name='MetaDataCategory',
),
migrations.DeleteModel(
name='MetaDataContent',
),
]

View File

@ -256,49 +256,6 @@ class AwardType(models.Model):
return self.name return self.name
class MetaDataCategory(models.Model):
"""MetaData category model."""
country = models.ForeignKey(
'location.Country', null=True, default=None, on_delete=models.CASCADE)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
public = models.BooleanField()
class MetaData(TranslatedFieldsMixin, models.Model):
"""MetaData model."""
label = TJSONField(
_('label'), null=True, blank=True,
default=None, help_text='{"en-GB":"some text"}')
category = models.ForeignKey(
MetaDataCategory, verbose_name=_('category'), on_delete=models.CASCADE)
class Meta:
verbose_name = _('metadata')
verbose_name_plural = _('metadata')
def __str__(self):
label = 'None'
lang = TranslationSettings.get_solo().default_language
if self.label and lang in self.label:
label = self.label[lang]
return f'id:{self.id}-{label}'
class MetaDataContentQuerySet(ContentTypeQuerySetMixin):
"""QuerySets for MetaDataContent model."""
class MetaDataContent(models.Model):
"""MetaDataContent model."""
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
metadata = models.ForeignKey(MetaData, on_delete=models.CASCADE)
objects = MetaDataContentQuerySet.as_manager()
class Currency(models.Model): class Currency(models.Model):
"""Currency model.""" """Currency model."""
name = models.CharField(_('name'), max_length=50) name = models.CharField(_('name'), max_length=50)

View File

@ -113,19 +113,6 @@ class AwardSerializer(AwardBaseSerializer):
fields = AwardBaseSerializer.Meta.fields + ['award_type', ] fields = AwardBaseSerializer.Meta.fields + ['award_type', ]
class MetaDataContentSerializer(serializers.ModelSerializer):
"""MetaData content serializer."""
id = serializers.IntegerField(source='metadata.id', read_only=True)
label_translated = TranslatedField(source='metadata.label_translated')
class Meta:
"""Meta class."""
model = models.MetaDataContent
fields = ('id', 'label_translated')
class CurrencySerializer(serializers.ModelSerializer): class CurrencySerializer(serializers.ModelSerializer):
"""Currency serializer""" """Currency serializer"""

View File

@ -146,8 +146,6 @@ class News(BaseAttributes, TranslatedFieldsMixin):
verbose_name=_('State')) verbose_name=_('State'))
is_highlighted = models.BooleanField(default=False, is_highlighted = models.BooleanField(default=False,
verbose_name=_('Is highlighted')) verbose_name=_('Is highlighted'))
# TODO: metadata_keys - описание ключей для динамического построения полей метаданных
# TODO: metadata_values - Описание значений для динамических полей из MetadataKeys
image_url = models.URLField(blank=True, null=True, default=None, image_url = models.URLField(blank=True, null=True, default=None,
verbose_name=_('Image URL path')) verbose_name=_('Image URL path'))
preview_image_url = models.URLField(blank=True, null=True, default=None, preview_image_url = models.URLField(blank=True, null=True, default=None,

View File

@ -4,9 +4,10 @@ app_name = 'mobile'
urlpatterns = [ urlpatterns = [
path('establishments/', include('establishment.urls.mobile')), path('establishments/', include('establishment.urls.mobile')),
path('location/', include('location.urls.mobile')),
path('main/', include('main.urls.mobile')),
path('tags/', include('tag.urls.mobile')), path('tags/', include('tag.urls.mobile')),
path('timetables/', include('timetable.urls.mobile')), path('timetables/', include('timetable.urls.mobile')),
path('main/', include('main.urls.mobile'))
# path('account/', include('account.urls.web')), # path('account/', include('account.urls.web')),
# path('advertisement/', include('advertisement.urls.web')), # path('advertisement/', include('advertisement.urls.web')),
# path('collection/', include('collection.urls.web')), # path('collection/', include('collection.urls.web')),