diff --git a/apps/collection/tests.py b/apps/collection/tests.py index ea13fff9..72b40c37 100644 --- a/apps/collection/tests.py +++ b/apps/collection/tests.py @@ -1,15 +1,15 @@ -import json, pytz +import json +import pytz from datetime import datetime -from rest_framework.test import APITestCase -from account.models import User -from rest_framework import status from http.cookies import SimpleCookie -from collection.models import Collection, Guide -from location.models import Country +from rest_framework import status +from rest_framework.test import APITestCase +from account.models import User +from collection.models import Collection, Guide from establishment.models import Establishment, EstablishmentType -# Create your tests here. +from location.models import Country class BaseTestCase(APITestCase): diff --git a/apps/collection/views/common.py b/apps/collection/views/common.py index 148c5fab..fd2a4584 100644 --- a/apps/collection/views/common.py +++ b/apps/collection/views/common.py @@ -4,7 +4,7 @@ from rest_framework import permissions from collection import models from utils.pagination import ProjectPageNumberPagination from django.shortcuts import get_object_or_404 -from establishment.serializers import EstablishmentListSerializer +from establishment.serializers import EstablishmentBaseSerializer from collection.serializers import common as serializers @@ -56,7 +56,7 @@ class CollectionEstablishmentListView(CollectionListView): """Retrieve list of establishment for collection.""" permission_classes = (permissions.AllowAny,) pagination_class = ProjectPageNumberPagination - serializer_class = EstablishmentListSerializer + serializer_class = EstablishmentBaseSerializer lookup_field = 'slug' def get_queryset(self): diff --git a/apps/establishment/models.py b/apps/establishment/models.py index 1d5be824..9caece11 100644 --- a/apps/establishment/models.py +++ b/apps/establishment/models.py @@ -8,13 +8,13 @@ from django.contrib.gis.geos import Point from django.contrib.gis.measure import Distance as DistanceMeasure from django.core.exceptions import ValidationError from django.db import models -from django.db.models import When, Case, F, ExpressionWrapper, Subquery +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 collection.models import Collection -from main.models import MetaDataContent +from main.models import Award, MetaDataContent from location.models import Address from review.models import Review from utils.models import (ProjectBaseMixin, TJSONField, URLImageMixin, @@ -281,7 +281,7 @@ class Establishment(ProjectBaseMixin, URLImageMixin, TranslatedFieldsMixin): slug = models.SlugField(unique=True, max_length=50, null=True, verbose_name=_('Establishment slug'), editable=True) - awards = generic.GenericRelation(to='main.Award') + awards = generic.GenericRelation(to='main.Award', related_query_name='establishment') tags = generic.GenericRelation(to='main.MetaDataContent') reviews = generic.GenericRelation(to='review.Review') comments = generic.GenericRelation(to='comment.Comment') @@ -330,6 +330,13 @@ class Establishment(ProjectBaseMixin, URLImageMixin, TranslatedFieldsMixin): raise ValidationError('Establishment type of subtype does not match') self.establishment_subtypes.add(establishment_subtype) + + @property + def vintage_year(self): + last_review = self.reviews.by_status(Review.READY).last() + if last_review: + return last_review.vintage + @property def best_price_menu(self): return 150 @@ -356,6 +363,11 @@ class Establishment(ProjectBaseMixin, URLImageMixin, TranslatedFieldsMixin): """ return self.address.coordinates + @property + def the_most_recent_award(self): + return Award.objects.filter(Q(establishment=self) | Q(employees__establishments=self)).latest( + field_name='vintage_year') + class Position(BaseAttributes, TranslatedFieldsMixin): """Position model.""" @@ -409,8 +421,8 @@ class Employee(BaseAttributes): verbose_name=_('User')) name = models.CharField(max_length=255, verbose_name=_('Last name')) establishments = models.ManyToManyField(Establishment, related_name='employees', - through=EstablishmentEmployee) - awards = generic.GenericRelation(to='main.Award') + through=EstablishmentEmployee,) + awards = generic.GenericRelation(to='main.Award', related_query_name='employees') tags = generic.GenericRelation(to='main.MetaDataContent') class Meta: diff --git a/apps/establishment/serializers/back.py b/apps/establishment/serializers/back.py index 5a15aafc..d0c70b2f 100644 --- a/apps/establishment/serializers/back.py +++ b/apps/establishment/serializers/back.py @@ -8,7 +8,6 @@ from establishment.serializers import ( from utils.decorators import with_base_attributes from main.models import Currency -from utils.serializers import TJSONSerializer class EstablishmentListCreateSerializer(EstablishmentBaseSerializer): @@ -89,13 +88,15 @@ class SocialNetworkSerializers(serializers.ModelSerializer): class PlatesSerializers(PlateSerializer): """Social network serializers.""" - name = TJSONSerializer + currency_id = serializers.PrimaryKeyRelatedField( source='currency', queryset=Currency.objects.all(), write_only=True ) class Meta: + """Meta class.""" + model = models.Plate fields = PlateSerializer.Meta.fields + [ 'name', diff --git a/apps/establishment/serializers/common.py b/apps/establishment/serializers/common.py index 0e33921c..f09c8200 100644 --- a/apps/establishment/serializers/common.py +++ b/apps/establishment/serializers/common.py @@ -1,18 +1,17 @@ """Establishment serializers.""" -from rest_framework import serializers from django.utils.translation import ugettext_lazy as _ +from rest_framework import serializers from comment import models as comment_models from comment.serializers import common as comment_serializers from establishment import models from favorites.models import Favorites -from location.serializers import AddressSimpleSerializer, AddressSerializer +from location.serializers import AddressBaseSerializer from main.models import MetaDataContent from main.serializers import MetaDataContentSerializer, AwardSerializer, CurrencySerializer from review import models as review_models from timetable.serialziers import ScheduleRUDSerializer from utils import exceptions as utils_exceptions -from utils.serializers import TranslatedField -from utils.serializers import TJSONSerializer +from utils.serializers import TranslatedField, ProjectModelSerializer class ContactPhonesSerializer(serializers.ModelSerializer): @@ -44,9 +43,9 @@ class SocialNetworkRelatedSerializers(serializers.ModelSerializer): ] -class PlateSerializer(serializers.ModelSerializer): +class PlateSerializer(ProjectModelSerializer): - name_translated = serializers.CharField(allow_null=True, read_only=True) + name_translated = TranslatedField() currency = CurrencySerializer(read_only=True) class Meta: @@ -59,9 +58,8 @@ class PlateSerializer(serializers.ModelSerializer): ] -class MenuSerializers(serializers.ModelSerializer): +class MenuSerializers(ProjectModelSerializer): plates = PlateSerializer(read_only=True, many=True, source='plate_set') - category = TJSONSerializer() category_translated = serializers.CharField(read_only=True) class Meta: @@ -75,9 +73,8 @@ class MenuSerializers(serializers.ModelSerializer): ] -class MenuRUDSerializers(serializers.ModelSerializer, ): +class MenuRUDSerializers(ProjectModelSerializer): plates = PlateSerializer(read_only=True, many=True, source='plate_set') - category = TJSONSerializer() class Meta: model = models.Menu @@ -141,13 +138,14 @@ class EstablishmentEmployeeSerializer(serializers.ModelSerializer): fields = ('id', 'name', 'position_translated', 'awards', 'priority') -class EstablishmentBaseSerializer(serializers.ModelSerializer): +class EstablishmentBaseSerializer(ProjectModelSerializer): """Base serializer for Establishment model.""" preview_image = serializers.URLField(source='preview_image_url') slug = serializers.SlugField(allow_blank=False, required=True, max_length=50) - address = AddressSerializer() + address = AddressBaseSerializer() tags = MetaDataContentSerializer(many=True) + in_favorites = serializers.BooleanField(allow_null=True) class Meta: """Meta class.""" @@ -168,27 +166,7 @@ class EstablishmentBaseSerializer(serializers.ModelSerializer): ] -class EstablishmentListSerializer(EstablishmentBaseSerializer): - """Serializer for Establishment model.""" - - in_favorites = serializers.BooleanField(allow_null=True) - - class Meta(EstablishmentBaseSerializer.Meta): - """Meta class.""" - - fields = EstablishmentBaseSerializer.Meta.fields + [ - 'in_favorites', - ] - -class EstablishmentAllListSerializer(EstablishmentListSerializer): - """ Serailizer for api/*/establishments """ - address = AddressSimpleSerializer() - - class Meta(EstablishmentListSerializer.Meta): - pass - - -class EstablishmentDetailSerializer(EstablishmentListSerializer): +class EstablishmentDetailSerializer(EstablishmentBaseSerializer): """Serializer for Establishment model.""" description_translated = TranslatedField() @@ -205,11 +183,12 @@ class EstablishmentDetailSerializer(EstablishmentListSerializer): menu = MenuSerializers(source='menu_set', many=True, read_only=True) best_price_menu = serializers.DecimalField(max_digits=14, decimal_places=2, read_only=True) best_price_carte = serializers.DecimalField(max_digits=14, decimal_places=2, read_only=True) + vintage_year = serializers.ReadOnlyField() - class Meta(EstablishmentListSerializer.Meta): + class Meta(EstablishmentBaseSerializer.Meta): """Meta class.""" - fields = EstablishmentListSerializer.Meta.fields + [ + fields = EstablishmentBaseSerializer.Meta.fields + [ 'description_translated', 'image', 'subtypes', @@ -229,18 +208,9 @@ class EstablishmentDetailSerializer(EstablishmentListSerializer): 'best_price_menu', 'best_price_carte', 'transportation', + 'vintage_year', ] - # def get_in_favorites(self, obj): - # """Get in_favorites status flag""" - # user = self.context.get('request').user - # if user.is_authenticated: - # return obj.id in user.favorites.by_content_type(app_label='establishment', - # model='establishment')\ - # .values_list('object_id', flat=True) - # else: - # return False - class EstablishmentCommentCreateSerializer(comment_serializers.CommentSerializer): """Create comment serializer""" diff --git a/apps/establishment/views/web.py b/apps/establishment/views/web.py index f4558b71..8f5d2a26 100644 --- a/apps/establishment/views/web.py +++ b/apps/establishment/views/web.py @@ -28,7 +28,7 @@ class EstablishmentListView(EstablishmentMixinView, generics.ListAPIView): """Resource for getting a list of establishments.""" filter_class = filters.EstablishmentFilter - serializer_class = serializers.EstablishmentAllListSerializer + serializer_class = serializers.EstablishmentBaseSerializer def get_queryset(self): """Overridden method 'get_queryset'.""" @@ -70,7 +70,8 @@ class EstablishmentRecentReviewListView(EstablishmentListView): class EstablishmentSimilarListView(EstablishmentListView): """Resource for getting a list of establishments.""" - serializer_class = serializers.EstablishmentListSerializer + + serializer_class = serializers.EstablishmentBaseSerializer pagination_class = EstablishmentPortionPagination def get_queryset(self): @@ -96,6 +97,7 @@ class EstablishmentCommentCreateView(generics.CreateAPIView): class EstablishmentCommentListView(generics.ListAPIView): """View for return list of establishment comments.""" + permission_classes = (permissions.AllowAny,) serializer_class = serializers.EstablishmentCommentCreateSerializer @@ -153,11 +155,13 @@ class EstablishmentFavoritesCreateDestroyView(generics.CreateAPIView, generics.D class EstablishmentNearestRetrieveView(EstablishmentListView, generics.ListAPIView): """Resource for getting list of nearest establishments.""" - serializer_class = serializers.EstablishmentListSerializer + + serializer_class = serializers.EstablishmentBaseSerializer filter_class = filters.EstablishmentFilter def get_queryset(self): """Overridden method 'get_queryset'.""" + # todo: latitude and longitude lat = self.request.query_params.get('lat') lon = self.request.query_params.get('lon') radius = self.request.query_params.get('radius') diff --git a/apps/favorites/views.py b/apps/favorites/views.py index a80960a8..5d99ed4b 100644 --- a/apps/favorites/views.py +++ b/apps/favorites/views.py @@ -1,13 +1,13 @@ """Views for app favorites.""" from rest_framework import generics - from establishment.models import Establishment -from establishment.serializers import EstablishmentListSerializer +from establishment.serializers import EstablishmentBaseSerializer from .models import Favorites class FavoritesBaseView(generics.GenericAPIView): """Base view for Favorites.""" + def get_queryset(self): """Override get_queryset method.""" return Favorites.objects.by_user(self.request.user) @@ -15,7 +15,8 @@ class FavoritesBaseView(generics.GenericAPIView): class FavoritesEstablishmentListView(generics.ListAPIView): """List views for favorites""" - serializer_class = EstablishmentListSerializer + + serializer_class = EstablishmentBaseSerializer def get_queryset(self): """Override get_queryset method""" diff --git a/apps/location/models.py b/apps/location/models.py index 7084385f..1cab1815 100644 --- a/apps/location/models.py +++ b/apps/location/models.py @@ -71,6 +71,7 @@ class City(models.Model): class Address(models.Model): + """Address model.""" city = models.ForeignKey(City, verbose_name=_('city'), on_delete=models.CASCADE) street_name_1 = models.CharField( @@ -98,11 +99,11 @@ class Address(models.Model): @property def latitude(self): - return self.coordinates.y + return self.coordinates.y if self.coordinates else float(0) @property def longitude(self): - return self.coordinates.x + return self.coordinates.x if self.coordinates else float(0) @property def location_field_indexing(self): diff --git a/apps/location/serializers/back.py b/apps/location/serializers/back.py index f3b36e64..f25aacf6 100644 --- a/apps/location/serializers/back.py +++ b/apps/location/serializers/back.py @@ -1,11 +1,8 @@ -from django.contrib.gis.geos import Point -from rest_framework import serializers - from location import models from location.serializers import common -class AddressCreateSerializer(common.AddressSerializer): +class AddressCreateSerializer(common.AddressDetailSerializer): """Address create serializer.""" diff --git a/apps/location/serializers/common.py b/apps/location/serializers/common.py index 37d782de..87d0df4e 100644 --- a/apps/location/serializers/common.py +++ b/apps/location/serializers/common.py @@ -1,5 +1,6 @@ """Location app common serializers.""" from django.contrib.gis.geos import Point +from django.utils.translation import ugettext_lazy as _ from rest_framework import serializers from location import models from utils.serializers import TranslatedField @@ -83,55 +84,18 @@ class CitySerializer(serializers.ModelSerializer): ] -class AddressSerializer(serializers.ModelSerializer): - """Address serializer.""" - - city_id = serializers.PrimaryKeyRelatedField( - source='city', - queryset=models.City.objects.all()) - city = CitySerializer(read_only=True) - geo_lon = serializers.FloatField(allow_null=True) - geo_lat = serializers.FloatField(allow_null=True) - - class Meta: - model = models.Address - fields = [ - 'id', - 'city_id', - 'city', - 'street_name_1', - 'street_name_2', - 'number', - 'postal_code', - 'geo_lon', - 'geo_lat', - ] - - def validate(self, attrs): - # if geo_lat and geo_lon was sent - geo_lat = attrs.pop('geo_lat') if 'geo_lat' in attrs else None - geo_lon = attrs.pop('geo_lon') if 'geo_lon' in attrs else None - - if geo_lat and geo_lon: - # Point(longitude, latitude) - attrs['coordinates'] = Point(geo_lat, geo_lon) - return attrs - - def to_representation(self, instance): - """Override to_representation method""" - if instance.coordinates and isinstance(instance.coordinates, Point): - # Point(longitude, latitude) - setattr(instance, 'geo_lat', instance.coordinates.x) - setattr(instance, 'geo_lon', instance.coordinates.y) - else: - setattr(instance, 'geo_lat', float(0)) - setattr(instance, 'geo_lon', float(0)) - return super().to_representation(instance) - - -class AddressSimpleSerializer(serializers.ModelSerializer): +class AddressBaseSerializer(serializers.ModelSerializer): """Serializer for address obj in related objects.""" + latitude = serializers.FloatField(allow_null=True) + longitude = serializers.FloatField(allow_null=True) + + # todo: remove this fields (backward compatibility) + geo_lon = serializers.FloatField(source='longitude', allow_null=True, + read_only=True) + geo_lat = serializers.FloatField(source='latitude', allow_null=True, + read_only=True) + class Meta: """Meta class.""" @@ -142,4 +106,45 @@ class AddressSimpleSerializer(serializers.ModelSerializer): 'street_name_2', 'number', 'postal_code', + 'latitude', + 'longitude', + + # todo: remove this fields (backward compatibility) + 'geo_lon', + 'geo_lat', + ) + + def validate_latitude(self, value): + if -90 <= value <= 90: + return value + raise serializers.ValidationError(_('Invalid value')) + + def validate_longitude(self, value): + if -180 <= value <= 180: + return value + raise serializers.ValidationError(_('Invalid value')) + + def validate(self, attrs): + # validate coordinates + latitude = attrs.pop('latitude', None) + longitude = attrs.pop('longitude', None) + if latitude is not None and longitude is not None: + attrs['coordinates'] = Point(longitude, latitude) + return attrs + + +class AddressDetailSerializer(AddressBaseSerializer): + """Address serializer.""" + + city_id = serializers.PrimaryKeyRelatedField( + source='city', write_only=True, + queryset=models.City.objects.all()) + city = CitySerializer(read_only=True) + + class Meta(AddressBaseSerializer.Meta): + """Meta class.""" + + fields = AddressBaseSerializer.Meta.fields + ( + 'city_id', + 'city', ) diff --git a/apps/location/views/back.py b/apps/location/views/back.py index 69ec28bc..ce6589ed 100644 --- a/apps/location/views/back.py +++ b/apps/location/views/back.py @@ -1,6 +1,5 @@ """Location app views.""" from rest_framework import generics -from rest_framework import permissions from location import models, serializers from location.views import common @@ -9,13 +8,13 @@ from location.views import common # Address class AddressListCreateView(common.AddressViewMixin, generics.ListCreateAPIView): """Create view for model Address.""" - serializer_class = serializers.AddressSerializer + serializer_class = serializers.AddressDetailSerializer queryset = models.Address.objects.all() class AddressRUDView(common.AddressViewMixin, generics.RetrieveUpdateDestroyAPIView): """RUD view for model Address.""" - serializer_class = serializers.AddressSerializer + serializer_class = serializers.AddressDetailSerializer queryset = models.Address.objects.all() diff --git a/apps/location/views/common.py b/apps/location/views/common.py index 6bc332ad..792fce91 100644 --- a/apps/location/views/common.py +++ b/apps/location/views/common.py @@ -100,17 +100,17 @@ class CityUpdateView(CityViewMixin, generics.UpdateAPIView): # Address class AddressCreateView(AddressViewMixin, generics.CreateAPIView): """Create view for model Address""" - serializer_class = serializers.AddressSerializer + serializer_class = serializers.AddressDetailSerializer class AddressRetrieveView(AddressViewMixin, generics.RetrieveAPIView): """Retrieve view for model Address""" - serializer_class = serializers.AddressSerializer + serializer_class = serializers.AddressDetailSerializer class AddressListView(AddressViewMixin, generics.ListAPIView): """List view for model Address""" permission_classes = (permissions.AllowAny, ) - serializer_class = serializers.AddressSerializer + serializer_class = serializers.AddressDetailSerializer diff --git a/apps/main/models.py b/apps/main/models.py index 47ac90be..2270cbf9 100644 --- a/apps/main/models.py +++ b/apps/main/models.py @@ -318,9 +318,9 @@ class Carousel(models.Model): @property def vintage_year(self): if hasattr(self.content_object, 'reviews'): - review_qs = self.content_object.reviews.by_status(Review.READY) - if review_qs.exists(): - return review_qs.last().vintage + last_review = self.content_object.reviews.by_status(Review.READY).last() + if last_review: + return last_review.vintage @property def toque_number(self): @@ -337,6 +337,16 @@ class Carousel(models.Model): if hasattr(self.content_object, 'image_url'): return self.content_object.image_url + @property + def slug(self): + if hasattr(self.content_object, 'slug'): + return self.content_object.slug + + @property + def the_most_recent_award(self): + if hasattr(self.content_object, 'the_most_recent_award'): + return self.content_object.the_most_recent_award + @property def model_name(self): return self.content_object.__class__.__name__ diff --git a/apps/main/serializers.py b/apps/main/serializers.py index c981f0ee..03ea73e6 100644 --- a/apps/main/serializers.py +++ b/apps/main/serializers.py @@ -3,6 +3,7 @@ from rest_framework import serializers from advertisement.serializers.web import AdvertisementSerializer from location.serializers import CountrySerializer from main import models +from establishment.models import Establishment from utils.serializers import TranslatedField @@ -141,6 +142,7 @@ class CarouselListSerializer(serializers.ModelSerializer): image = serializers.URLField(source='image_url') awards = AwardBaseSerializer(many=True) vintage_year = serializers.IntegerField() + last_award = AwardBaseSerializer(source='the_most_recent_award', allow_null=True) class Meta: """Meta class.""" @@ -154,6 +156,8 @@ class CarouselListSerializer(serializers.ModelSerializer): 'public_mark', 'image', 'vintage_year', + 'last_award', + 'slug', ] diff --git a/apps/news/serializers.py b/apps/news/serializers.py index fad2f355..8bed7692 100644 --- a/apps/news/serializers.py +++ b/apps/news/serializers.py @@ -9,7 +9,7 @@ from location import models as location_models from location.serializers import CountrySimpleSerializer from main.serializers import MetaDataContentSerializer from news import models -from utils.serializers import TranslatedField +from utils.serializers import TranslatedField, ProjectModelSerializer class NewsImageSerializer(ImageSerializer): @@ -41,7 +41,7 @@ class NewsTypeSerializer(serializers.ModelSerializer): fields = ('id', 'name') -class NewsBaseSerializer(serializers.ModelSerializer): +class NewsBaseSerializer(ProjectModelSerializer): """Base serializer for News model.""" # read only fields @@ -74,7 +74,8 @@ class NewsDetailSerializer(NewsBaseSerializer): description_translated = TranslatedField() country = CountrySimpleSerializer(read_only=True) - author = UserSerializer(source='created_by') + # todo: check the data redundancy + author = UserSerializer(source='created_by', read_only=True) state_display = serializers.CharField(source='get_state_display', read_only=True) diff --git a/apps/news/views.py b/apps/news/views.py index 3eb7f9ab..ca2c01cd 100644 --- a/apps/news/views.py +++ b/apps/news/views.py @@ -23,11 +23,13 @@ class NewsMixinView: class NewsListView(NewsMixinView, generics.ListAPIView): """News list view.""" + filter_class = filters.NewsListFilterSet class NewsDetailView(NewsMixinView, generics.RetrieveAPIView): """News detail view.""" + lookup_field = 'slug' serializer_class = serializers.NewsDetailSerializer @@ -57,6 +59,7 @@ class NewsBackOfficeLCView(NewsBackOfficeMixinView, create_serializers_class = serializers.NewsBackOfficeDetailSerializer def get_serializer_class(self): + """Override serializer class.""" if self.request.method == 'POST': return self.create_serializers_class return super().get_serializer_class() diff --git a/apps/timetable/models.py b/apps/timetable/models.py index e1e7fae7..53670d02 100644 --- a/apps/timetable/models.py +++ b/apps/timetable/models.py @@ -36,3 +36,4 @@ class Timetable(ProjectBaseMixin): """Meta class.""" verbose_name = _('Timetable') verbose_name_plural = _('Timetables') + ordering = ['weekday'] diff --git a/apps/utils/serializers.py b/apps/utils/serializers.py index d30a046c..2b2282d1 100644 --- a/apps/utils/serializers.py +++ b/apps/utils/serializers.py @@ -1,7 +1,7 @@ """Utils app serializer.""" -from rest_framework import serializers -from utils.models import PlatformMixin from django.core import exceptions +from rest_framework import serializers +from utils import models from translation.models import Language @@ -11,8 +11,8 @@ class EmptySerializer(serializers.Serializer): class SourceSerializerMixin(serializers.Serializer): """Base authorization serializer mixin""" - source = serializers.ChoiceField(choices=PlatformMixin.SOURCES, - default=PlatformMixin.WEB, + source = serializers.ChoiceField(choices=models.PlatformMixin.SOURCES, + default=models.PlatformMixin.WEB, write_only=True) @@ -25,18 +25,16 @@ class TranslatedField(serializers.CharField): read_only=read_only, **kwargs) +# todo: view validation in more detail def validate_tjson(value): - if not isinstance(value, dict): raise exceptions.ValidationError( 'invalid_json', code='invalid_json', params={'value': value}, ) - lang_count = Language.objects.filter(locale__in=value.keys()).count() - - if lang_count == 0: + if lang_count != len(value.keys()): raise exceptions.ValidationError( 'invalid_translated_keys', code='invalid_translated_keys', @@ -44,5 +42,13 @@ def validate_tjson(value): ) -class TJSONSerializer(serializers.JSONField): +class TJSONField(serializers.JSONField): + """Custom serializer's JSONField for model's TJSONField.""" + validators = [validate_tjson] + + +class ProjectModelSerializer(serializers.ModelSerializer): + """Overrided ModelSerializer.""" + + serializers.ModelSerializer.serializer_field_mapping[models.TJSONField] = TJSONField diff --git a/docker-compose.yml b/docker-compose.yml index 3fb05f98..7c4e49d2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,8 +12,6 @@ services: - POSTGRES_DB=postgres ports: - "5436:5432" - networks: - - db-net volumes: - gm-db:/var/lib/postgresql/data/ elasticsearch: @@ -28,8 +26,7 @@ services: - "ES_JAVA_OPTS=-Xms512m -Xmx512m" - discovery.type=single-node - xpack.security.enabled=false - networks: - - app-net + # RabbitMQ rabbitmq: image: rabbitmq:latest @@ -83,19 +80,12 @@ services: - worker - worker_beat - elasticsearch - networks: - - app-net - - db-net volumes: - .:/code - gm-media:/media-data ports: - "8000:8000" -networks: - app-net: - db-net: - volumes: gm-db: name: gm-db diff --git a/project/settings/local.py b/project/settings/local.py index a7cb7c0f..f67b8f7e 100644 --- a/project/settings/local.py +++ b/project/settings/local.py @@ -1,5 +1,6 @@ """Local settings.""" from .base import * +import sys ALLOWED_HOSTS = ['*', ] @@ -57,6 +58,7 @@ LOGGING = { } } + # ELASTICSEARCH SETTINGS ELASTICSEARCH_DSL = { 'default': { @@ -66,8 +68,13 @@ ELASTICSEARCH_DSL = { ELASTICSEARCH_INDEX_NAMES = { # 'search_indexes.documents.news': 'local_news', - 'search_indexes.documents.establishment': 'local_establishment', + 'search_indexes.documents.establishment': 'local_establishment', } +TESTING = sys.argv[1:2] == ['test'] +if TESTING: + ELASTICSEARCH_INDEX_NAMES = {} + + # SORL thumbnails THUMBNAIL_DEBUG = True