Translation & establishment

This commit is contained in:
evgeniy-st 2019-08-28 15:21:28 +03:00
parent f65b1caf9a
commit 1aef1a5bb1
12 changed files with 187 additions and 51 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,17 +1,17 @@
"""Establishment models.""" """Establishment models."""
from django.contrib.postgres.fields import JSONField
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
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 location.models import Address from location.models import Address
from utils.models import ProjectBaseMixin, ImageMixin, LocaleManagerMixin from utils.models import ProjectBaseMixin, ImageMixin, TJSONField, TraslatedFieldsMixin
# todo: establishment type&subtypes check # todo: establishment type&subtypes check
class EstablishmentType(ProjectBaseMixin): class EstablishmentType(ProjectBaseMixin, TraslatedFieldsMixin):
"""Establishment type model.""" """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) use_subtypes = models.BooleanField(_('Use subtypes'), default=True)
class Meta: class Meta:
@ -20,10 +20,6 @@ class EstablishmentType(ProjectBaseMixin):
verbose_name = _('Establishment type') verbose_name = _('Establishment type')
verbose_name_plural = _('Establishment types') verbose_name_plural = _('Establishment types')
def __str__(self):
"""__str__ method."""
return self.name
class EstablishmentSubTypeManager(models.Manager): class EstablishmentSubTypeManager(models.Manager):
"""Extended manager for establishment subtype.""" """Extended manager for establishment subtype."""
@ -35,10 +31,11 @@ class EstablishmentSubTypeManager(models.Manager):
return obj return obj
class EstablishmentSubType(ProjectBaseMixin): class EstablishmentSubType(ProjectBaseMixin, TraslatedFieldsMixin):
"""Establishment type model.""" """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, establishment_type = models.ForeignKey(EstablishmentType,
on_delete=models.CASCADE, on_delete=models.CASCADE,
verbose_name=_('Type')) verbose_name=_('Type'))
@ -60,18 +57,14 @@ class EstablishmentSubType(ProjectBaseMixin):
raise ValidationError(_('Establishment type is not use subtypes.')) raise ValidationError(_('Establishment type is not use subtypes.'))
class EstablishmentManager(LocaleManagerMixin): class Establishment(ProjectBaseMixin, ImageMixin, TraslatedFieldsMixin):
"""Extended manager for establishment model."""
class Establishment(ProjectBaseMixin, ImageMixin):
"""Establishment model.""" """Establishment model."""
name = JSONField(blank=True, null=True, default=None, name = TJSONField(blank=True, null=True, default=None,
verbose_name=_('Name'), help_text='{"en":"some text"}') verbose_name=_('Name'), help_text='{"en":"some text"}')
description = JSONField(blank=True, null=True, default=None, description = TJSONField(blank=True, null=True, default=None,
verbose_name=_('Description'), verbose_name=_('Description'),
help_text='{"en":"some text"}') help_text='{"en":"some text"}')
public_mark = models.PositiveIntegerField(blank=True, null=True, public_mark = models.PositiveIntegerField(blank=True, null=True,
default=None, default=None,
verbose_name=_('Public mark'),) verbose_name=_('Public mark'),)
@ -92,8 +85,6 @@ class Establishment(ProjectBaseMixin, ImageMixin):
default=None, default=None,
verbose_name=_('Price level')) verbose_name=_('Price level'))
objects = EstablishmentManager()
class Meta: class Meta:
"""Meta class.""" """Meta class."""

View File

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

View File

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

View File

@ -10,7 +10,13 @@ class EstablishmentListView(JWTGenericViewMixin, generics.ListAPIView):
pagination_class = None pagination_class = None
permission_classes = (permissions.AllowAny,) permission_classes = (permissions.AllowAny,)
serializer_class = serializers.EstablishmentSerializer serializer_class = serializers.EstablishmentSerializer
queryset = models.Establishment.objects.all()
def get_queryset(self):
return models.Establishment.objects.annotate_localized_fields( class EstablishmentTypeListView(JWTGenericViewMixin, generics.ListAPIView):
locale=self.request.locale) """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.db.transaction import on_commit
from django.dispatch import receiver from django.dispatch import receiver
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from utils.models import ProjectBaseMixin, LocaleManagerMixin, SVGImageMixin from utils.models import ProjectBaseMixin, LocaleManagerMixin, SVGImageMixin

View File

@ -1,16 +1,31 @@
from django.utils.deprecation import MiddlewareMixin """Custom middleware."""
from django.utils import translation
class CookieMiddleware(MiddlewareMixin): def get_locale(cookie_dict):
"""Middleware to handle cookies""" 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.""" """Utils app models."""
from os.path import exists from os.path import exists
from django.contrib.auth.tokens import PasswordResetTokenGenerator from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.contrib.gis.db import models from django.contrib.gis.db import models
from django.contrib.postgres.fields import JSONField from django.contrib.postgres.fields import JSONField
from django.contrib.postgres.fields.jsonb import KeyTextTransform from django.contrib.postgres.fields.jsonb import KeyTextTransform
from django.utils import timezone from django.utils import timezone
from django.utils.html import mark_safe 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 easy_thumbnails.fields import ThumbnailerImageField
from utils.methods import image_path, svg_image_path from utils.methods import image_path, svg_image_path
from utils.validators import svg_image_validator from utils.validators import svg_image_validator
@ -28,6 +26,30 @@ class ProjectBaseMixin(models.Model):
abstract = True 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: class OAuthProjectMixin:
"""OAuth2 mixin for project GM""" """OAuth2 mixin for project GM"""

View File

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

View File

@ -18,10 +18,10 @@ from django.urls import path, include
app_name = 'web' app_name = 'web'
urlpatterns = [ urlpatterns = [
path('', include('establishment.urls.web')),
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')),
path('establishments/', include('establishment.urls.web')),
path('news/', include('news.urls.web')), path('news/', include('news.urls.web')),
path('partner/', include('partner.urls.web')), path('partner/', include('partner.urls.web')),
] ]