Merge branch 'develop' into feature/gm-148
# Conflicts: # apps/news/serializers.py # project/settings/local.py
This commit is contained in:
commit
b31e71d4ef
|
|
@ -1,15 +1,15 @@
|
||||||
import json, pytz
|
import json
|
||||||
|
import pytz
|
||||||
from datetime import datetime
|
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 http.cookies import SimpleCookie
|
||||||
|
|
||||||
from collection.models import Collection, Guide
|
from rest_framework import status
|
||||||
from location.models import Country
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
|
from account.models import User
|
||||||
|
from collection.models import Collection, Guide
|
||||||
from establishment.models import Establishment, EstablishmentType
|
from establishment.models import Establishment, EstablishmentType
|
||||||
# Create your tests here.
|
from location.models import Country
|
||||||
|
|
||||||
|
|
||||||
class BaseTestCase(APITestCase):
|
class BaseTestCase(APITestCase):
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ from rest_framework import permissions
|
||||||
from collection import models
|
from collection import models
|
||||||
from utils.pagination import ProjectPageNumberPagination
|
from utils.pagination import ProjectPageNumberPagination
|
||||||
from django.shortcuts import get_object_or_404
|
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
|
from collection.serializers import common as serializers
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -56,7 +56,7 @@ class CollectionEstablishmentListView(CollectionListView):
|
||||||
"""Retrieve list of establishment for collection."""
|
"""Retrieve list of establishment for collection."""
|
||||||
permission_classes = (permissions.AllowAny,)
|
permission_classes = (permissions.AllowAny,)
|
||||||
pagination_class = ProjectPageNumberPagination
|
pagination_class = ProjectPageNumberPagination
|
||||||
serializer_class = EstablishmentListSerializer
|
serializer_class = EstablishmentBaseSerializer
|
||||||
lookup_field = 'slug'
|
lookup_field = 'slug'
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,13 @@ from django.contrib.gis.geos import Point
|
||||||
from django.contrib.gis.measure import Distance as DistanceMeasure
|
from django.contrib.gis.measure import Distance as DistanceMeasure
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
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 import timezone
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from phonenumber_field.modelfields import PhoneNumberField
|
from phonenumber_field.modelfields import PhoneNumberField
|
||||||
|
|
||||||
from collection.models import Collection
|
from collection.models import Collection
|
||||||
from main.models import MetaDataContent
|
from main.models import Award, MetaDataContent
|
||||||
from location.models import Address
|
from location.models import Address
|
||||||
from review.models import Review
|
from review.models import Review
|
||||||
from utils.models import (ProjectBaseMixin, TJSONField, URLImageMixin,
|
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,
|
slug = models.SlugField(unique=True, max_length=50, null=True,
|
||||||
verbose_name=_('Establishment slug'), editable=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')
|
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')
|
||||||
|
|
@ -330,6 +330,13 @@ class Establishment(ProjectBaseMixin, URLImageMixin, TranslatedFieldsMixin):
|
||||||
raise ValidationError('Establishment type of subtype does not match')
|
raise ValidationError('Establishment type of subtype does not match')
|
||||||
self.establishment_subtypes.add(establishment_subtype)
|
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
|
@property
|
||||||
def best_price_menu(self):
|
def best_price_menu(self):
|
||||||
return 150
|
return 150
|
||||||
|
|
@ -356,6 +363,11 @@ class Establishment(ProjectBaseMixin, URLImageMixin, TranslatedFieldsMixin):
|
||||||
"""
|
"""
|
||||||
return self.address.coordinates
|
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):
|
class Position(BaseAttributes, TranslatedFieldsMixin):
|
||||||
"""Position model."""
|
"""Position model."""
|
||||||
|
|
@ -409,8 +421,8 @@ class Employee(BaseAttributes):
|
||||||
verbose_name=_('User'))
|
verbose_name=_('User'))
|
||||||
name = models.CharField(max_length=255, verbose_name=_('Last name'))
|
name = models.CharField(max_length=255, verbose_name=_('Last name'))
|
||||||
establishments = models.ManyToManyField(Establishment, related_name='employees',
|
establishments = models.ManyToManyField(Establishment, related_name='employees',
|
||||||
through=EstablishmentEmployee)
|
through=EstablishmentEmployee,)
|
||||||
awards = generic.GenericRelation(to='main.Award')
|
awards = generic.GenericRelation(to='main.Award', related_query_name='employees')
|
||||||
tags = generic.GenericRelation(to='main.MetaDataContent')
|
tags = generic.GenericRelation(to='main.MetaDataContent')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ from establishment.serializers import (
|
||||||
from utils.decorators import with_base_attributes
|
from utils.decorators import with_base_attributes
|
||||||
|
|
||||||
from main.models import Currency
|
from main.models import Currency
|
||||||
from utils.serializers import TJSONSerializer
|
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentListCreateSerializer(EstablishmentBaseSerializer):
|
class EstablishmentListCreateSerializer(EstablishmentBaseSerializer):
|
||||||
|
|
@ -89,13 +88,15 @@ class SocialNetworkSerializers(serializers.ModelSerializer):
|
||||||
|
|
||||||
class PlatesSerializers(PlateSerializer):
|
class PlatesSerializers(PlateSerializer):
|
||||||
"""Social network serializers."""
|
"""Social network serializers."""
|
||||||
name = TJSONSerializer
|
|
||||||
currency_id = serializers.PrimaryKeyRelatedField(
|
currency_id = serializers.PrimaryKeyRelatedField(
|
||||||
source='currency',
|
source='currency',
|
||||||
queryset=Currency.objects.all(), write_only=True
|
queryset=Currency.objects.all(), write_only=True
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
"""Meta class."""
|
||||||
|
|
||||||
model = models.Plate
|
model = models.Plate
|
||||||
fields = PlateSerializer.Meta.fields + [
|
fields = PlateSerializer.Meta.fields + [
|
||||||
'name',
|
'name',
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,17 @@
|
||||||
"""Establishment serializers."""
|
"""Establishment serializers."""
|
||||||
from rest_framework import serializers
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
from rest_framework import serializers
|
||||||
from comment import models as comment_models
|
from comment import models as comment_models
|
||||||
from comment.serializers import common as comment_serializers
|
from comment.serializers import common as comment_serializers
|
||||||
from establishment import models
|
from establishment import models
|
||||||
from favorites.models import Favorites
|
from favorites.models import Favorites
|
||||||
from location.serializers import AddressSimpleSerializer, AddressSerializer
|
from location.serializers import AddressBaseSerializer
|
||||||
from main.models import MetaDataContent
|
from main.models import MetaDataContent
|
||||||
from main.serializers import MetaDataContentSerializer, AwardSerializer, CurrencySerializer
|
from main.serializers import MetaDataContentSerializer, AwardSerializer, CurrencySerializer
|
||||||
from review import models as review_models
|
from review import models as review_models
|
||||||
from timetable.serialziers import ScheduleRUDSerializer
|
from timetable.serialziers import ScheduleRUDSerializer
|
||||||
from utils import exceptions as utils_exceptions
|
from utils import exceptions as utils_exceptions
|
||||||
from utils.serializers import TranslatedField
|
from utils.serializers import TranslatedField, ProjectModelSerializer
|
||||||
from utils.serializers import TJSONSerializer
|
|
||||||
|
|
||||||
|
|
||||||
class ContactPhonesSerializer(serializers.ModelSerializer):
|
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)
|
currency = CurrencySerializer(read_only=True)
|
||||||
|
|
||||||
class Meta:
|
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')
|
plates = PlateSerializer(read_only=True, many=True, source='plate_set')
|
||||||
category = TJSONSerializer()
|
|
||||||
category_translated = serializers.CharField(read_only=True)
|
category_translated = serializers.CharField(read_only=True)
|
||||||
|
|
||||||
class Meta:
|
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')
|
plates = PlateSerializer(read_only=True, many=True, source='plate_set')
|
||||||
category = TJSONSerializer()
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.Menu
|
model = models.Menu
|
||||||
|
|
@ -141,13 +138,14 @@ class EstablishmentEmployeeSerializer(serializers.ModelSerializer):
|
||||||
fields = ('id', 'name', 'position_translated', 'awards', 'priority')
|
fields = ('id', 'name', 'position_translated', 'awards', 'priority')
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentBaseSerializer(serializers.ModelSerializer):
|
class EstablishmentBaseSerializer(ProjectModelSerializer):
|
||||||
"""Base serializer for Establishment model."""
|
"""Base serializer for Establishment model."""
|
||||||
|
|
||||||
preview_image = serializers.URLField(source='preview_image_url')
|
preview_image = serializers.URLField(source='preview_image_url')
|
||||||
slug = serializers.SlugField(allow_blank=False, required=True, max_length=50)
|
slug = serializers.SlugField(allow_blank=False, required=True, max_length=50)
|
||||||
address = AddressSerializer()
|
address = AddressBaseSerializer()
|
||||||
tags = MetaDataContentSerializer(many=True)
|
tags = MetaDataContentSerializer(many=True)
|
||||||
|
in_favorites = serializers.BooleanField(allow_null=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""Meta class."""
|
"""Meta class."""
|
||||||
|
|
@ -168,27 +166,7 @@ class EstablishmentBaseSerializer(serializers.ModelSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentListSerializer(EstablishmentBaseSerializer):
|
class EstablishmentDetailSerializer(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):
|
|
||||||
"""Serializer for Establishment model."""
|
"""Serializer for Establishment model."""
|
||||||
|
|
||||||
description_translated = TranslatedField()
|
description_translated = TranslatedField()
|
||||||
|
|
@ -205,11 +183,12 @@ class EstablishmentDetailSerializer(EstablishmentListSerializer):
|
||||||
menu = MenuSerializers(source='menu_set', many=True, read_only=True)
|
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_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)
|
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."""
|
"""Meta class."""
|
||||||
|
|
||||||
fields = EstablishmentListSerializer.Meta.fields + [
|
fields = EstablishmentBaseSerializer.Meta.fields + [
|
||||||
'description_translated',
|
'description_translated',
|
||||||
'image',
|
'image',
|
||||||
'subtypes',
|
'subtypes',
|
||||||
|
|
@ -229,18 +208,9 @@ class EstablishmentDetailSerializer(EstablishmentListSerializer):
|
||||||
'best_price_menu',
|
'best_price_menu',
|
||||||
'best_price_carte',
|
'best_price_carte',
|
||||||
'transportation',
|
'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):
|
class EstablishmentCommentCreateSerializer(comment_serializers.CommentSerializer):
|
||||||
"""Create comment serializer"""
|
"""Create comment serializer"""
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ class EstablishmentListView(EstablishmentMixinView, generics.ListAPIView):
|
||||||
"""Resource for getting a list of establishments."""
|
"""Resource for getting a list of establishments."""
|
||||||
|
|
||||||
filter_class = filters.EstablishmentFilter
|
filter_class = filters.EstablishmentFilter
|
||||||
serializer_class = serializers.EstablishmentAllListSerializer
|
serializer_class = serializers.EstablishmentBaseSerializer
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
"""Overridden method 'get_queryset'."""
|
"""Overridden method 'get_queryset'."""
|
||||||
|
|
@ -70,7 +70,8 @@ class EstablishmentRecentReviewListView(EstablishmentListView):
|
||||||
|
|
||||||
class EstablishmentSimilarListView(EstablishmentListView):
|
class EstablishmentSimilarListView(EstablishmentListView):
|
||||||
"""Resource for getting a list of establishments."""
|
"""Resource for getting a list of establishments."""
|
||||||
serializer_class = serializers.EstablishmentListSerializer
|
|
||||||
|
serializer_class = serializers.EstablishmentBaseSerializer
|
||||||
pagination_class = EstablishmentPortionPagination
|
pagination_class = EstablishmentPortionPagination
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
|
@ -96,6 +97,7 @@ class EstablishmentCommentCreateView(generics.CreateAPIView):
|
||||||
|
|
||||||
class EstablishmentCommentListView(generics.ListAPIView):
|
class EstablishmentCommentListView(generics.ListAPIView):
|
||||||
"""View for return list of establishment comments."""
|
"""View for return list of establishment comments."""
|
||||||
|
|
||||||
permission_classes = (permissions.AllowAny,)
|
permission_classes = (permissions.AllowAny,)
|
||||||
serializer_class = serializers.EstablishmentCommentCreateSerializer
|
serializer_class = serializers.EstablishmentCommentCreateSerializer
|
||||||
|
|
||||||
|
|
@ -153,11 +155,13 @@ class EstablishmentFavoritesCreateDestroyView(generics.CreateAPIView, generics.D
|
||||||
|
|
||||||
class EstablishmentNearestRetrieveView(EstablishmentListView, generics.ListAPIView):
|
class EstablishmentNearestRetrieveView(EstablishmentListView, generics.ListAPIView):
|
||||||
"""Resource for getting list of nearest establishments."""
|
"""Resource for getting list of nearest establishments."""
|
||||||
serializer_class = serializers.EstablishmentListSerializer
|
|
||||||
|
serializer_class = serializers.EstablishmentBaseSerializer
|
||||||
filter_class = filters.EstablishmentFilter
|
filter_class = filters.EstablishmentFilter
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
"""Overridden method 'get_queryset'."""
|
"""Overridden method 'get_queryset'."""
|
||||||
|
# todo: latitude and longitude
|
||||||
lat = self.request.query_params.get('lat')
|
lat = self.request.query_params.get('lat')
|
||||||
lon = self.request.query_params.get('lon')
|
lon = self.request.query_params.get('lon')
|
||||||
radius = self.request.query_params.get('radius')
|
radius = self.request.query_params.get('radius')
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
"""Views for app favorites."""
|
"""Views for app favorites."""
|
||||||
from rest_framework import generics
|
from rest_framework import generics
|
||||||
|
|
||||||
from establishment.models import Establishment
|
from establishment.models import Establishment
|
||||||
from establishment.serializers import EstablishmentListSerializer
|
from establishment.serializers import EstablishmentBaseSerializer
|
||||||
from .models import Favorites
|
from .models import Favorites
|
||||||
|
|
||||||
|
|
||||||
class FavoritesBaseView(generics.GenericAPIView):
|
class FavoritesBaseView(generics.GenericAPIView):
|
||||||
"""Base view for Favorites."""
|
"""Base view for Favorites."""
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
"""Override get_queryset method."""
|
"""Override get_queryset method."""
|
||||||
return Favorites.objects.by_user(self.request.user)
|
return Favorites.objects.by_user(self.request.user)
|
||||||
|
|
@ -15,7 +15,8 @@ class FavoritesBaseView(generics.GenericAPIView):
|
||||||
|
|
||||||
class FavoritesEstablishmentListView(generics.ListAPIView):
|
class FavoritesEstablishmentListView(generics.ListAPIView):
|
||||||
"""List views for favorites"""
|
"""List views for favorites"""
|
||||||
serializer_class = EstablishmentListSerializer
|
|
||||||
|
serializer_class = EstablishmentBaseSerializer
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
"""Override get_queryset method"""
|
"""Override get_queryset method"""
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ 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(
|
||||||
|
|
@ -98,11 +99,11 @@ class Address(models.Model):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def latitude(self):
|
def latitude(self):
|
||||||
return self.coordinates.y
|
return self.coordinates.y if self.coordinates else float(0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def longitude(self):
|
def longitude(self):
|
||||||
return self.coordinates.x
|
return self.coordinates.x if self.coordinates else float(0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def location_field_indexing(self):
|
def location_field_indexing(self):
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,8 @@
|
||||||
from django.contrib.gis.geos import Point
|
|
||||||
from rest_framework import serializers
|
|
||||||
|
|
||||||
from location import models
|
from location import models
|
||||||
from location.serializers import common
|
from location.serializers import common
|
||||||
|
|
||||||
|
|
||||||
class AddressCreateSerializer(common.AddressSerializer):
|
class AddressCreateSerializer(common.AddressDetailSerializer):
|
||||||
"""Address create serializer."""
|
"""Address create serializer."""
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
"""Location app common serializers."""
|
"""Location app common serializers."""
|
||||||
from django.contrib.gis.geos import Point
|
from django.contrib.gis.geos import Point
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from location import models
|
from location import models
|
||||||
from utils.serializers import TranslatedField
|
from utils.serializers import TranslatedField
|
||||||
|
|
@ -83,55 +84,18 @@ class CitySerializer(serializers.ModelSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class AddressSerializer(serializers.ModelSerializer):
|
class AddressBaseSerializer(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):
|
|
||||||
"""Serializer for address obj in related objects."""
|
"""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:
|
class Meta:
|
||||||
"""Meta class."""
|
"""Meta class."""
|
||||||
|
|
||||||
|
|
@ -142,4 +106,45 @@ class AddressSimpleSerializer(serializers.ModelSerializer):
|
||||||
'street_name_2',
|
'street_name_2',
|
||||||
'number',
|
'number',
|
||||||
'postal_code',
|
'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',
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
"""Location app views."""
|
"""Location app views."""
|
||||||
from rest_framework import generics
|
from rest_framework import generics
|
||||||
from rest_framework import permissions
|
|
||||||
|
|
||||||
from location import models, serializers
|
from location import models, serializers
|
||||||
from location.views import common
|
from location.views import common
|
||||||
|
|
@ -9,13 +8,13 @@ from location.views import common
|
||||||
# Address
|
# Address
|
||||||
class AddressListCreateView(common.AddressViewMixin, generics.ListCreateAPIView):
|
class AddressListCreateView(common.AddressViewMixin, generics.ListCreateAPIView):
|
||||||
"""Create view for model Address."""
|
"""Create view for model Address."""
|
||||||
serializer_class = serializers.AddressSerializer
|
serializer_class = serializers.AddressDetailSerializer
|
||||||
queryset = models.Address.objects.all()
|
queryset = models.Address.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class AddressRUDView(common.AddressViewMixin, generics.RetrieveUpdateDestroyAPIView):
|
class AddressRUDView(common.AddressViewMixin, generics.RetrieveUpdateDestroyAPIView):
|
||||||
"""RUD view for model Address."""
|
"""RUD view for model Address."""
|
||||||
serializer_class = serializers.AddressSerializer
|
serializer_class = serializers.AddressDetailSerializer
|
||||||
queryset = models.Address.objects.all()
|
queryset = models.Address.objects.all()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -100,17 +100,17 @@ class CityUpdateView(CityViewMixin, generics.UpdateAPIView):
|
||||||
# Address
|
# Address
|
||||||
class AddressCreateView(AddressViewMixin, generics.CreateAPIView):
|
class AddressCreateView(AddressViewMixin, generics.CreateAPIView):
|
||||||
"""Create view for model Address"""
|
"""Create view for model Address"""
|
||||||
serializer_class = serializers.AddressSerializer
|
serializer_class = serializers.AddressDetailSerializer
|
||||||
|
|
||||||
|
|
||||||
class AddressRetrieveView(AddressViewMixin, generics.RetrieveAPIView):
|
class AddressRetrieveView(AddressViewMixin, generics.RetrieveAPIView):
|
||||||
"""Retrieve view for model Address"""
|
"""Retrieve view for model Address"""
|
||||||
serializer_class = serializers.AddressSerializer
|
serializer_class = serializers.AddressDetailSerializer
|
||||||
|
|
||||||
|
|
||||||
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.AddressSerializer
|
serializer_class = serializers.AddressDetailSerializer
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -318,9 +318,9 @@ class Carousel(models.Model):
|
||||||
@property
|
@property
|
||||||
def vintage_year(self):
|
def vintage_year(self):
|
||||||
if hasattr(self.content_object, 'reviews'):
|
if hasattr(self.content_object, 'reviews'):
|
||||||
review_qs = self.content_object.reviews.by_status(Review.READY)
|
last_review = self.content_object.reviews.by_status(Review.READY).last()
|
||||||
if review_qs.exists():
|
if last_review:
|
||||||
return review_qs.last().vintage
|
return last_review.vintage
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def toque_number(self):
|
def toque_number(self):
|
||||||
|
|
@ -337,6 +337,16 @@ class Carousel(models.Model):
|
||||||
if hasattr(self.content_object, 'image_url'):
|
if hasattr(self.content_object, 'image_url'):
|
||||||
return 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
|
@property
|
||||||
def model_name(self):
|
def model_name(self):
|
||||||
return self.content_object.__class__.__name__
|
return self.content_object.__class__.__name__
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ from rest_framework import serializers
|
||||||
from advertisement.serializers.web import AdvertisementSerializer
|
from advertisement.serializers.web import AdvertisementSerializer
|
||||||
from location.serializers import CountrySerializer
|
from location.serializers import CountrySerializer
|
||||||
from main import models
|
from main import models
|
||||||
|
from establishment.models import Establishment
|
||||||
from utils.serializers import TranslatedField
|
from utils.serializers import TranslatedField
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -141,6 +142,7 @@ class CarouselListSerializer(serializers.ModelSerializer):
|
||||||
image = serializers.URLField(source='image_url')
|
image = serializers.URLField(source='image_url')
|
||||||
awards = AwardBaseSerializer(many=True)
|
awards = AwardBaseSerializer(many=True)
|
||||||
vintage_year = serializers.IntegerField()
|
vintage_year = serializers.IntegerField()
|
||||||
|
last_award = AwardBaseSerializer(source='the_most_recent_award', allow_null=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""Meta class."""
|
"""Meta class."""
|
||||||
|
|
@ -154,6 +156,8 @@ class CarouselListSerializer(serializers.ModelSerializer):
|
||||||
'public_mark',
|
'public_mark',
|
||||||
'image',
|
'image',
|
||||||
'vintage_year',
|
'vintage_year',
|
||||||
|
'last_award',
|
||||||
|
'slug',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ from location import models as location_models
|
||||||
from location.serializers import CountrySimpleSerializer
|
from location.serializers import CountrySimpleSerializer
|
||||||
from main.serializers import MetaDataContentSerializer
|
from main.serializers import MetaDataContentSerializer
|
||||||
from news import models
|
from news import models
|
||||||
from utils.serializers import TranslatedField
|
from utils.serializers import TranslatedField, ProjectModelSerializer
|
||||||
|
|
||||||
|
|
||||||
class NewsImageSerializer(ImageSerializer):
|
class NewsImageSerializer(ImageSerializer):
|
||||||
|
|
@ -41,7 +41,7 @@ class NewsTypeSerializer(serializers.ModelSerializer):
|
||||||
fields = ('id', 'name')
|
fields = ('id', 'name')
|
||||||
|
|
||||||
|
|
||||||
class NewsBaseSerializer(serializers.ModelSerializer):
|
class NewsBaseSerializer(ProjectModelSerializer):
|
||||||
"""Base serializer for News model."""
|
"""Base serializer for News model."""
|
||||||
|
|
||||||
# read only fields
|
# read only fields
|
||||||
|
|
@ -74,7 +74,8 @@ class NewsDetailSerializer(NewsBaseSerializer):
|
||||||
|
|
||||||
description_translated = TranslatedField()
|
description_translated = TranslatedField()
|
||||||
country = CountrySimpleSerializer(read_only=True)
|
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',
|
state_display = serializers.CharField(source='get_state_display',
|
||||||
read_only=True)
|
read_only=True)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,13 @@ class NewsMixinView:
|
||||||
|
|
||||||
class NewsListView(NewsMixinView, generics.ListAPIView):
|
class NewsListView(NewsMixinView, generics.ListAPIView):
|
||||||
"""News list view."""
|
"""News list view."""
|
||||||
|
|
||||||
filter_class = filters.NewsListFilterSet
|
filter_class = filters.NewsListFilterSet
|
||||||
|
|
||||||
|
|
||||||
class NewsDetailView(NewsMixinView, generics.RetrieveAPIView):
|
class NewsDetailView(NewsMixinView, generics.RetrieveAPIView):
|
||||||
"""News detail view."""
|
"""News detail view."""
|
||||||
|
|
||||||
lookup_field = 'slug'
|
lookup_field = 'slug'
|
||||||
serializer_class = serializers.NewsDetailSerializer
|
serializer_class = serializers.NewsDetailSerializer
|
||||||
|
|
||||||
|
|
@ -57,6 +59,7 @@ class NewsBackOfficeLCView(NewsBackOfficeMixinView,
|
||||||
create_serializers_class = serializers.NewsBackOfficeDetailSerializer
|
create_serializers_class = serializers.NewsBackOfficeDetailSerializer
|
||||||
|
|
||||||
def get_serializer_class(self):
|
def get_serializer_class(self):
|
||||||
|
"""Override serializer class."""
|
||||||
if self.request.method == 'POST':
|
if self.request.method == 'POST':
|
||||||
return self.create_serializers_class
|
return self.create_serializers_class
|
||||||
return super().get_serializer_class()
|
return super().get_serializer_class()
|
||||||
|
|
|
||||||
|
|
@ -36,3 +36,4 @@ class Timetable(ProjectBaseMixin):
|
||||||
"""Meta class."""
|
"""Meta class."""
|
||||||
verbose_name = _('Timetable')
|
verbose_name = _('Timetable')
|
||||||
verbose_name_plural = _('Timetables')
|
verbose_name_plural = _('Timetables')
|
||||||
|
ordering = ['weekday']
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"""Utils app serializer."""
|
"""Utils app serializer."""
|
||||||
from rest_framework import serializers
|
|
||||||
from utils.models import PlatformMixin
|
|
||||||
from django.core import exceptions
|
from django.core import exceptions
|
||||||
|
from rest_framework import serializers
|
||||||
|
from utils import models
|
||||||
from translation.models import Language
|
from translation.models import Language
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -11,8 +11,8 @@ class EmptySerializer(serializers.Serializer):
|
||||||
|
|
||||||
class SourceSerializerMixin(serializers.Serializer):
|
class SourceSerializerMixin(serializers.Serializer):
|
||||||
"""Base authorization serializer mixin"""
|
"""Base authorization serializer mixin"""
|
||||||
source = serializers.ChoiceField(choices=PlatformMixin.SOURCES,
|
source = serializers.ChoiceField(choices=models.PlatformMixin.SOURCES,
|
||||||
default=PlatformMixin.WEB,
|
default=models.PlatformMixin.WEB,
|
||||||
write_only=True)
|
write_only=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -25,18 +25,16 @@ class TranslatedField(serializers.CharField):
|
||||||
read_only=read_only, **kwargs)
|
read_only=read_only, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
# todo: view validation in more detail
|
||||||
def validate_tjson(value):
|
def validate_tjson(value):
|
||||||
|
|
||||||
if not isinstance(value, dict):
|
if not isinstance(value, dict):
|
||||||
raise exceptions.ValidationError(
|
raise exceptions.ValidationError(
|
||||||
'invalid_json',
|
'invalid_json',
|
||||||
code='invalid_json',
|
code='invalid_json',
|
||||||
params={'value': value},
|
params={'value': value},
|
||||||
)
|
)
|
||||||
|
|
||||||
lang_count = Language.objects.filter(locale__in=value.keys()).count()
|
lang_count = Language.objects.filter(locale__in=value.keys()).count()
|
||||||
|
if lang_count != len(value.keys()):
|
||||||
if lang_count == 0:
|
|
||||||
raise exceptions.ValidationError(
|
raise exceptions.ValidationError(
|
||||||
'invalid_translated_keys',
|
'invalid_translated_keys',
|
||||||
code='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]
|
validators = [validate_tjson]
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectModelSerializer(serializers.ModelSerializer):
|
||||||
|
"""Overrided ModelSerializer."""
|
||||||
|
|
||||||
|
serializers.ModelSerializer.serializer_field_mapping[models.TJSONField] = TJSONField
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,6 @@ services:
|
||||||
- POSTGRES_DB=postgres
|
- POSTGRES_DB=postgres
|
||||||
ports:
|
ports:
|
||||||
- "5436:5432"
|
- "5436:5432"
|
||||||
networks:
|
|
||||||
- db-net
|
|
||||||
volumes:
|
volumes:
|
||||||
- gm-db:/var/lib/postgresql/data/
|
- gm-db:/var/lib/postgresql/data/
|
||||||
elasticsearch:
|
elasticsearch:
|
||||||
|
|
@ -28,8 +26,7 @@ services:
|
||||||
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
|
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
|
||||||
- discovery.type=single-node
|
- discovery.type=single-node
|
||||||
- xpack.security.enabled=false
|
- xpack.security.enabled=false
|
||||||
networks:
|
|
||||||
- app-net
|
|
||||||
# RabbitMQ
|
# RabbitMQ
|
||||||
rabbitmq:
|
rabbitmq:
|
||||||
image: rabbitmq:latest
|
image: rabbitmq:latest
|
||||||
|
|
@ -83,19 +80,12 @@ services:
|
||||||
- worker
|
- worker
|
||||||
- worker_beat
|
- worker_beat
|
||||||
- elasticsearch
|
- elasticsearch
|
||||||
networks:
|
|
||||||
- app-net
|
|
||||||
- db-net
|
|
||||||
volumes:
|
volumes:
|
||||||
- .:/code
|
- .:/code
|
||||||
- gm-media:/media-data
|
- gm-media:/media-data
|
||||||
ports:
|
ports:
|
||||||
- "8000:8000"
|
- "8000:8000"
|
||||||
|
|
||||||
networks:
|
|
||||||
app-net:
|
|
||||||
db-net:
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
gm-db:
|
gm-db:
|
||||||
name: gm-db
|
name: gm-db
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
"""Local settings."""
|
"""Local settings."""
|
||||||
from .base import *
|
from .base import *
|
||||||
|
import sys
|
||||||
|
|
||||||
ALLOWED_HOSTS = ['*', ]
|
ALLOWED_HOSTS = ['*', ]
|
||||||
|
|
||||||
|
|
@ -57,6 +58,7 @@ LOGGING = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# ELASTICSEARCH SETTINGS
|
# ELASTICSEARCH SETTINGS
|
||||||
ELASTICSEARCH_DSL = {
|
ELASTICSEARCH_DSL = {
|
||||||
'default': {
|
'default': {
|
||||||
|
|
@ -69,5 +71,10 @@ ELASTICSEARCH_INDEX_NAMES = {
|
||||||
'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
|
# SORL thumbnails
|
||||||
THUMBNAIL_DEBUG = True
|
THUMBNAIL_DEBUG = True
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user