Merge branch 'feature/establishment' into develop

This commit is contained in:
evgeniy-st 2019-08-28 15:35:41 +03:00
commit 0f748ec714
15 changed files with 203 additions and 59 deletions

View File

@ -0,0 +1,37 @@
# Generated by Django 2.2.4 on 2019-08-28 09:09
from django.db import migrations
import utils.models
class Migration(migrations.Migration):
dependencies = [
('establishment', '0001_initial'),
]
operations = [
migrations.RenameField(
model_name='establishmenttype',
old_name='name',
new_name='name_bak',
),
migrations.AddField(
model_name='establishmenttype',
name='name',
field=utils.models.TJSONField(blank=True, default=None, help_text='{"en":"some text"}',
null=True, verbose_name='Description'),
),
migrations.RenameField(
model_name='establishmentsubtype',
old_name='name',
new_name='name_bak',
),
migrations.AddField(
model_name='establishmentsubtype',
name='name',
field=utils.models.TJSONField(blank=True, default=None, help_text='{"en":"some text"}',
null=True, verbose_name='Description'),
),
]

View File

@ -0,0 +1,37 @@
# Generated by Django 2.2.4 on 2019-08-28 11:40
from django.db import migrations
def copy_establishment_type(apps, schemaeditor):
EstablishmentType = apps.get_model('establishment', 'EstablishmentType')
for et in EstablishmentType.objects.all():
et.name = {'en': str(et.name_bak)}
et.save()
def copy_establishment_subtype(apps, schemaeditor):
EstablishmentSubType = apps.get_model('establishment', 'EstablishmentSubType')
for est in EstablishmentSubType.objects.all():
est.name = {'en': str(est.name_bak)}
est.save()
class Migration(migrations.Migration):
dependencies = [
('establishment', '0002_auto_20190828_0909'),
]
operations = [
migrations.RunPython(copy_establishment_type, migrations.RunPython.noop),
migrations.RunPython(copy_establishment_subtype, migrations.RunPython.noop),
migrations.RemoveField(
model_name='establishmentsubtype',
name='name_bak',
),
migrations.RemoveField(
model_name='establishmenttype',
name='name_bak',
),
]

View File

@ -0,0 +1,24 @@
# Generated by Django 2.2.4 on 2019-08-28 11:56
from django.db import migrations
import utils.models
class Migration(migrations.Migration):
dependencies = [
('establishment', '0003_auto_20190828_1140'),
]
operations = [
migrations.AlterField(
model_name='establishment',
name='description',
field=utils.models.TJSONField(blank=True, default=None, help_text='{"en":"some text"}', null=True, verbose_name='Description'),
),
migrations.AlterField(
model_name='establishment',
name='name',
field=utils.models.TJSONField(blank=True, default=None, help_text='{"en":"some text"}', null=True, verbose_name='Name'),
),
]

View File

@ -1,18 +1,18 @@
"""Establishment models."""
from django.contrib.postgres.fields import JSONField
from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import gettext_lazy as _
from location.models import Address
from utils.models import ProjectBaseMixin, ImageMixin, LocaleManagerMixin
from utils.models import ProjectBaseMixin, ImageMixin, TJSONField, TraslatedFieldsMixin
from django.contrib.contenttypes import fields as generic
# todo: establishment type&subtypes check
class EstablishmentType(ProjectBaseMixin):
class EstablishmentType(ProjectBaseMixin, TraslatedFieldsMixin):
"""Establishment type model."""
name = models.CharField(_('Name'), max_length=255, unique=True)
name = TJSONField(blank=True, null=True, default=None, verbose_name=_('Description'),
help_text='{"en":"some text"}')
use_subtypes = models.BooleanField(_('Use subtypes'), default=True)
class Meta:
@ -21,10 +21,6 @@ class EstablishmentType(ProjectBaseMixin):
verbose_name = _('Establishment type')
verbose_name_plural = _('Establishment types')
def __str__(self):
"""__str__ method."""
return self.name
class EstablishmentSubTypeManager(models.Manager):
"""Extended manager for establishment subtype."""
@ -36,10 +32,11 @@ class EstablishmentSubTypeManager(models.Manager):
return obj
class EstablishmentSubType(ProjectBaseMixin):
class EstablishmentSubType(ProjectBaseMixin, TraslatedFieldsMixin):
"""Establishment type model."""
name = models.CharField(_('Name'), max_length=255, unique=True)
name = TJSONField(blank=True, null=True, default=None, verbose_name=_('Description'),
help_text='{"en":"some text"}')
establishment_type = models.ForeignKey(EstablishmentType,
on_delete=models.CASCADE,
verbose_name=_('Type'))
@ -61,18 +58,14 @@ class EstablishmentSubType(ProjectBaseMixin):
raise ValidationError(_('Establishment type is not use subtypes.'))
class EstablishmentManager(LocaleManagerMixin):
"""Extended manager for establishment model."""
class Establishment(ProjectBaseMixin, ImageMixin):
class Establishment(ProjectBaseMixin, ImageMixin, TraslatedFieldsMixin):
"""Establishment model."""
name = JSONField(blank=True, null=True, default=None,
verbose_name=_('Name'), help_text='{"en":"some text"}')
description = JSONField(blank=True, null=True, default=None,
verbose_name=_('Description'),
help_text='{"en":"some text"}')
name = TJSONField(blank=True, null=True, default=None,
verbose_name=_('Name'), help_text='{"en":"some text"}')
description = TJSONField(blank=True, null=True, default=None,
verbose_name=_('Description'),
help_text='{"en":"some text"}')
public_mark = models.PositiveIntegerField(blank=True, null=True,
default=None,
verbose_name=_('Public mark'),)
@ -94,8 +87,6 @@ class Establishment(ProjectBaseMixin, ImageMixin):
verbose_name=_('Price level'))
awards = generic.GenericRelation(to='main.Award')
objects = EstablishmentManager()
class Meta:
"""Meta class."""

View File

@ -7,28 +7,32 @@ from location.serializers import AddressSerializer
class EstablishmentTypeSerializer(serializers.ModelSerializer):
"""Serializer for EstablishmentType model."""
name_translated = serializers.CharField(allow_null=True)
class Meta:
"""Meta class."""
model = models.EstablishmentType
fields = ('id', 'name',)
fields = ('id', 'name_translated')
class EstablishmentSubTypeSerializer(serializers.ModelSerializer):
"""Serializer for EstablishmentSubType models."""
name_translated = serializers.CharField(allow_null=True)
class Meta:
"""Meta class."""
model = models.EstablishmentSubType
fields = ('id', 'name')
fields = ('id', 'name_translated')
class EstablishmentSerializer(serializers.ModelSerializer):
"""Serializer for Establishment model."""
name_trans = serializers.CharField()
description_trans = serializers.CharField()
name_translated = serializers.CharField(allow_null=True)
description_translated = serializers.CharField(allow_null=True)
type = EstablishmentTypeSerializer(source='establishment_type')
subtypes = EstablishmentSubTypeSerializer(many=True)
address = AddressSerializer()
@ -39,8 +43,8 @@ class EstablishmentSerializer(serializers.ModelSerializer):
model = models.Establishment
fields = (
'id',
'name_trans',
'description_trans',
'name_translated',
'description_translated',
'public_mark',
'price_level',
'type',

View File

@ -7,5 +7,5 @@ app_name = 'establishment'
urlpatterns = [
path('', views.EstablishmentListView.as_view(), name='establishment-list'),
path('', views.EstablishmentListView.as_view(), name='list'),
]

View File

@ -10,7 +10,13 @@ class EstablishmentListView(JWTGenericViewMixin, generics.ListAPIView):
pagination_class = None
permission_classes = (permissions.AllowAny,)
serializer_class = serializers.EstablishmentSerializer
queryset = models.Establishment.objects.all()
def get_queryset(self):
return models.Establishment.objects.annotate_localized_fields(
locale=self.request.locale)
class EstablishmentTypeListView(JWTGenericViewMixin, generics.ListAPIView):
"""Resource for getting a list of establishment types."""
pagination_class = None
permission_classes = (permissions.AllowAny,)
serializer_class = serializers.EstablishmentTypeSerializer
queryset = models.EstablishmentType.objects.all()

View File

@ -6,7 +6,6 @@ from django.db.models.signals import post_save
from django.db.transaction import on_commit
from django.dispatch import receiver
from django.utils.translation import gettext_lazy as _
from utils.models import ProjectBaseMixin, LocaleManagerMixin, SVGImageMixin

View File

@ -13,9 +13,6 @@ class CountryViewMixin(JWTGenericViewMixin, generics.GenericAPIView):
serializer_class = serializers.CountrySerializer
permission_classes = (permissions.AllowAny, )
def get_queryset(self):
return models.Country.objects.annotate_localized_fields(locale=self.request.locale)
class RegionViewMixin(generics.GenericAPIView):
"""View Mixin for model Region"""
@ -41,10 +38,16 @@ class CountryListView(CountryViewMixin, generics.ListAPIView):
pagination_class = None
def get_queryset(self):
return models.Country.objects.annotate_localized_fields(locale=self.request.locale)
class CountryRetrieveView(CountryViewMixin, generics.RetrieveAPIView):
"""Retrieve view for model Country."""
def get_queryset(self):
return models.Country.objects.annotate_localized_fields(locale=self.request.locale)
# Region
class RegionCreateView(RegionViewMixin, generics.CreateAPIView):

View File

@ -2,12 +2,14 @@
from rest_framework import generics, permissions
from rest_framework.response import Response
from main import methods, models, serializers
from utils.serializers import EmptySerializer
class DetermineSiteView(generics.GenericAPIView):
"""Determine user's site."""
permission_classes = (permissions.AllowAny,)
serializer_class = EmptySerializer
def get(self, request, *args, **kwargs):
user_ip = methods.get_user_ip(request)

View File

@ -1,16 +1,31 @@
from django.utils.deprecation import MiddlewareMixin
"""Custom middleware."""
from django.utils import translation
class CookieMiddleware(MiddlewareMixin):
"""Middleware to handle cookies"""
def get_locale(cookie_dict):
return cookie_dict.get('locale')
def get_country_code(cookie_dict):
return cookie_dict.get('country_code')
def parse_cookies(get_response):
"""Parse cookies."""
def middleware(request):
cookie_dict = request.COOKIES
# processing locale cookie
locale = get_locale(cookie_dict)
if locale:
translation.activate(locale)
request.locale = locale
# processing country country cookie
country_code = get_country_code(cookie_dict)
request.country_code = country_code
response = get_response(request)
return response
return middleware
def process_request(self, request):
# Check locale in cookies if locale not exists in DB return 406
# if 'locale' not in request.COOKIES or \
# not Language.objects.by_locale(request.COOKIES.get('locale'))\
# .exists():
# return HttpResponse(status=status.HTTP_406_NOT_ACCEPTABLE)
#
# Add to request attrs from cookie
for cookie in request.COOKIES:
setattr(request, cookie, request.COOKIES[cookie])

View File

@ -1,15 +1,13 @@
"""Utils app models."""
from os.path import exists
from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.contrib.gis.db import models
from django.contrib.postgres.fields import JSONField
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 _
from django.utils.translation import ugettext_lazy as _, get_language
from easy_thumbnails.fields import ThumbnailerImageField
from utils.methods import image_path, svg_image_path
from utils.validators import svg_image_validator
@ -28,6 +26,30 @@ class ProjectBaseMixin(models.Model):
abstract = True
class TJSONField(JSONField):
"""Overrided JsonField."""
def translate_field(self, field_name):
def translate(self):
field = getattr(self, field_name)
if isinstance(field, dict):
return field.get(get_language())
return None
return translate
class TraslatedFieldsMixin:
def __init__(self, *args, **kwargs):
super(TraslatedFieldsMixin, self).__init__(*args, **kwargs)
cls = self.__class__
for field in cls._meta.fields:
field_name = field.name
if isinstance(field, TJSONField):
setattr(cls, f'{field.name}_translated',
property(translate_field(self, field_name)))
class OAuthProjectMixin:
"""OAuth2 mixin for project GM"""

View File

@ -0,0 +1,6 @@
"""Utils app serializer."""
from rest_framework import serializers
class EmptySerializer(serializers.Serializer):
"""Empty Serializer"""

View File

@ -85,9 +85,9 @@ INSTALLED_APPS = CONTRIB_APPS + PROJECT_APPS + EXTERNAL_APPS
MIDDLEWARE = [
'utils.middleware.CookieMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'oauth2_provider.middleware.OAuth2TokenMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
@ -95,6 +95,7 @@ MIDDLEWARE = [
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'utils.middleware.parse_cookies',
]
ROOT_URLCONF = 'project.urls'

View File

@ -24,10 +24,7 @@ urlpatterns = [
path('establishments/', include('establishment.urls.web')),
path('news/', include('news.urls.web')),
path('partner/', include('partner.urls.web')),
path('location/', include(('location.urls', 'location'),
namespace='location')),
path('main/', include(('main.urls', 'main'),
namespace='main')),
path('translation/', include(('translation.urls', 'translation'),
namespace='translation')),
path('location/', include('location.urls')),
path('main/', include('main.urls')),
path('translation/', include('translation.urls')),
]