Merge branch 'develop' into feature/establishment-tests-api-status
This commit is contained in:
commit
7f973bbf52
|
|
@ -8,11 +8,6 @@ class CollectionAdmin(admin.ModelAdmin):
|
||||||
"""Collection admin."""
|
"""Collection admin."""
|
||||||
|
|
||||||
|
|
||||||
@admin.register(models.CollectionItem)
|
|
||||||
class CollectionItemAdmin(admin.ModelAdmin):
|
|
||||||
"""CollectionItem admin."""
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(models.Guide)
|
@admin.register(models.Guide)
|
||||||
class GuideAdmin(admin.ModelAdmin):
|
class GuideAdmin(admin.ModelAdmin):
|
||||||
"""Guide admin."""
|
"""Guide admin."""
|
||||||
|
|
|
||||||
16
apps/collection/migrations/0009_delete_collectionitem.py
Normal file
16
apps/collection/migrations/0009_delete_collectionitem.py
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-20 08:55
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('collection', '0008_auto_20190916_1158'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='CollectionItem',
|
||||||
|
),
|
||||||
|
]
|
||||||
19
apps/collection/migrations/0010_collection_description.py
Normal file
19
apps/collection/migrations/0010_collection_description.py
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-20 09:27
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
import utils.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('collection', '0009_delete_collectionitem'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='collection',
|
||||||
|
name='description',
|
||||||
|
field=utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='description'),
|
||||||
|
),
|
||||||
|
]
|
||||||
22
apps/collection/migrations/0011_auto_20190920_1059.py
Normal file
22
apps/collection/migrations/0011_auto_20190920_1059.py
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-20 10:59
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('collection', '0010_collection_description'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='collection',
|
||||||
|
name='image',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='collection',
|
||||||
|
name='image_url',
|
||||||
|
field=models.URLField(blank=True, default=None, null=True, verbose_name='Image URL path'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
from django.contrib.postgres.fields import JSONField
|
from django.contrib.postgres.fields import JSONField
|
||||||
from django.contrib.contenttypes.fields import ContentType
|
from django.contrib.contenttypes.fields import ContentType
|
||||||
from django.contrib.contenttypes import fields as generic
|
from utils.models import TJSONField
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from utils.models import ProjectBaseMixin, ImageMixin
|
from utils.models import ProjectBaseMixin, URLImageMixin
|
||||||
|
from utils.models import TranslatedFieldsMixin
|
||||||
|
|
||||||
|
|
||||||
# Mixins
|
# Mixins
|
||||||
|
|
@ -40,7 +41,8 @@ class CollectionQuerySet(models.QuerySet):
|
||||||
return self.filter(is_publish=True)
|
return self.filter(is_publish=True)
|
||||||
|
|
||||||
|
|
||||||
class Collection(ProjectBaseMixin, CollectionNameMixin, CollectionDateMixin):
|
class Collection(ProjectBaseMixin, CollectionNameMixin, CollectionDateMixin,
|
||||||
|
TranslatedFieldsMixin, URLImageMixin):
|
||||||
"""Collection model."""
|
"""Collection model."""
|
||||||
ORDINARY = 0 # Ordinary collection
|
ORDINARY = 0 # Ordinary collection
|
||||||
POP = 1 # POP collection
|
POP = 1 # POP collection
|
||||||
|
|
@ -53,9 +55,6 @@ class Collection(ProjectBaseMixin, CollectionNameMixin, CollectionDateMixin):
|
||||||
collection_type = models.PositiveSmallIntegerField(choices=COLLECTION_TYPES,
|
collection_type = models.PositiveSmallIntegerField(choices=COLLECTION_TYPES,
|
||||||
default=ORDINARY,
|
default=ORDINARY,
|
||||||
verbose_name=_('Collection type'))
|
verbose_name=_('Collection type'))
|
||||||
image = models.ForeignKey(
|
|
||||||
'gallery.Image', null=True, blank=True, default=None,
|
|
||||||
verbose_name=_('Collection image'), on_delete=models.CASCADE)
|
|
||||||
is_publish = models.BooleanField(
|
is_publish = models.BooleanField(
|
||||||
default=False, verbose_name=_('Publish status'))
|
default=False, verbose_name=_('Publish status'))
|
||||||
on_top = models.BooleanField(
|
on_top = models.BooleanField(
|
||||||
|
|
@ -65,6 +64,9 @@ class Collection(ProjectBaseMixin, CollectionNameMixin, CollectionDateMixin):
|
||||||
block_size = JSONField(
|
block_size = JSONField(
|
||||||
_('collection block properties'), null=True, blank=True,
|
_('collection block properties'), null=True, blank=True,
|
||||||
default=None, help_text='{"width": "250px", "height":"250px"}')
|
default=None, help_text='{"width": "250px", "height":"250px"}')
|
||||||
|
description = TJSONField(
|
||||||
|
_('description'), null=True, blank=True,
|
||||||
|
default=None, help_text='{"en-GB":"some text"}')
|
||||||
|
|
||||||
objects = CollectionQuerySet.as_manager()
|
objects = CollectionQuerySet.as_manager()
|
||||||
|
|
||||||
|
|
@ -78,26 +80,6 @@ class Collection(ProjectBaseMixin, CollectionNameMixin, CollectionDateMixin):
|
||||||
return f'{self.name}'
|
return f'{self.name}'
|
||||||
|
|
||||||
|
|
||||||
class CollectionItemQuerySet(models.QuerySet):
|
|
||||||
"""QuerySet for model CollectionItem."""
|
|
||||||
|
|
||||||
def by_collection(self, collection_id):
|
|
||||||
"""Filter by collection id"""
|
|
||||||
return self.filter(collection=collection_id)
|
|
||||||
|
|
||||||
|
|
||||||
class CollectionItem(ProjectBaseMixin):
|
|
||||||
"""CollectionItem model."""
|
|
||||||
collection = models.ForeignKey(
|
|
||||||
Collection, verbose_name=_('collection'), on_delete=models.CASCADE)
|
|
||||||
content_type = models.ForeignKey(ContentType, default=None,
|
|
||||||
null=True, blank=True, on_delete=models.CASCADE)
|
|
||||||
object_id = models.PositiveIntegerField(default=None, null=True, blank=True)
|
|
||||||
content_object = generic.GenericForeignKey('content_type', 'object_id')
|
|
||||||
|
|
||||||
objects = CollectionItemQuerySet.as_manager()
|
|
||||||
|
|
||||||
|
|
||||||
class GuideQuerySet(models.QuerySet):
|
class GuideQuerySet(models.QuerySet):
|
||||||
"""QuerySet for Guide."""
|
"""QuerySet for Guide."""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from collection import models
|
from collection import models
|
||||||
from gallery import models as gallery_models
|
|
||||||
from location import models as location_models
|
from location import models as location_models
|
||||||
|
|
||||||
|
|
||||||
class CollectionSerializer(serializers.ModelSerializer):
|
class CollectionSerializer(serializers.ModelSerializer):
|
||||||
"""Collection serializer"""
|
"""Collection serializer"""
|
||||||
# RESPONSE
|
# RESPONSE
|
||||||
image_url = serializers.ImageField(source='image.image')
|
description_translated = serializers.CharField(read_only=True, allow_null=True)
|
||||||
|
|
||||||
# COMMON
|
# COMMON
|
||||||
block_size = serializers.JSONField()
|
block_size = serializers.JSONField()
|
||||||
|
|
@ -21,18 +20,15 @@ class CollectionSerializer(serializers.ModelSerializer):
|
||||||
country = serializers.PrimaryKeyRelatedField(
|
country = serializers.PrimaryKeyRelatedField(
|
||||||
queryset=location_models.Country.objects.all(),
|
queryset=location_models.Country.objects.all(),
|
||||||
write_only=True)
|
write_only=True)
|
||||||
image = serializers.PrimaryKeyRelatedField(
|
|
||||||
queryset=gallery_models.Image.objects.all(),
|
|
||||||
write_only=True)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.Collection
|
model = models.Collection
|
||||||
fields = [
|
fields = [
|
||||||
'id',
|
'id',
|
||||||
'name',
|
'name',
|
||||||
|
'description_translated',
|
||||||
'start',
|
'start',
|
||||||
'end',
|
'end',
|
||||||
'image',
|
|
||||||
'image_url',
|
'image_url',
|
||||||
'is_publish',
|
'is_publish',
|
||||||
'on_top',
|
'on_top',
|
||||||
|
|
@ -41,18 +37,6 @@ class CollectionSerializer(serializers.ModelSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class CollectionItemSerializer(serializers.ModelSerializer):
|
|
||||||
"""CollectionItem serializer"""
|
|
||||||
class Meta:
|
|
||||||
model = models.CollectionItem
|
|
||||||
fields = [
|
|
||||||
'id',
|
|
||||||
'collection',
|
|
||||||
'content_type',
|
|
||||||
'object_id',
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class GuideSerializer(serializers.ModelSerializer):
|
class GuideSerializer(serializers.ModelSerializer):
|
||||||
"""Guide serializer"""
|
"""Guide serializer"""
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,8 @@ app_name = 'collection'
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', views.CollectionListView.as_view(), name='list'),
|
path('', views.CollectionListView.as_view(), name='list'),
|
||||||
path('<int:pk>/', views.CollectionRetrieveView.as_view(), name='detail'),
|
path('<int:pk>/establishments/', views.CollectionEstablishmentListView.as_view(),
|
||||||
|
name='detail'),
|
||||||
path('items/', views.CollectionItemListView.as_view(), name='collection-items-list'),
|
|
||||||
path('items/<int:pk>/', views.CollectionItemRetrieveView.as_view(),
|
|
||||||
name='collection-items-detail'),
|
|
||||||
|
|
||||||
path('guides/', views.GuideListView.as_view(), name='guides-list'),
|
path('guides/', views.GuideListView.as_view(), name='guides-list'),
|
||||||
path('guides/<int:pk>/', views.GuideRetrieveView.as_view(), name='guides-detail'),
|
path('guides/<int:pk>/', views.GuideRetrieveView.as_view(), name='guides-detail'),
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@ from rest_framework import generics
|
||||||
from rest_framework import permissions
|
from rest_framework import permissions
|
||||||
|
|
||||||
from collection import models
|
from collection import models
|
||||||
|
from utils.pagination import ProjectPageNumberPagination
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
|
from establishment.serializers import EstablishmentListSerializer
|
||||||
from collection.serializers import common as serializers
|
from collection.serializers import common as serializers
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -12,12 +15,6 @@ class CollectionViewMixin(generics.GenericAPIView):
|
||||||
queryset = models.Collection.objects.all()
|
queryset = models.Collection.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class CollectionItemViewMixin(generics.GenericAPIView):
|
|
||||||
"""Mixin for CollectionItem view"""
|
|
||||||
model = models.CollectionItem
|
|
||||||
queryset = models.CollectionItem.objects.all()
|
|
||||||
|
|
||||||
|
|
||||||
class GuideViewMixin(generics.GenericAPIView):
|
class GuideViewMixin(generics.GenericAPIView):
|
||||||
"""Mixin for Guide view"""
|
"""Mixin for Guide view"""
|
||||||
model = models.Guide
|
model = models.Guide
|
||||||
|
|
@ -28,7 +25,6 @@ class GuideViewMixin(generics.GenericAPIView):
|
||||||
# Collections
|
# Collections
|
||||||
class CollectionListView(CollectionViewMixin, generics.ListAPIView):
|
class CollectionListView(CollectionViewMixin, generics.ListAPIView):
|
||||||
"""List Collection view"""
|
"""List Collection view"""
|
||||||
pagination_class = None
|
|
||||||
permission_classes = (permissions.AllowAny,)
|
permission_classes = (permissions.AllowAny,)
|
||||||
serializer_class = serializers.CollectionSerializer
|
serializer_class = serializers.CollectionSerializer
|
||||||
|
|
||||||
|
|
@ -39,23 +35,24 @@ class CollectionListView(CollectionViewMixin, generics.ListAPIView):
|
||||||
.order_by('-on_top', '-created')
|
.order_by('-on_top', '-created')
|
||||||
|
|
||||||
|
|
||||||
class CollectionRetrieveView(CollectionViewMixin, generics.RetrieveAPIView):
|
class CollectionEstablishmentListView(CollectionListView):
|
||||||
"""Retrieve Collection view"""
|
"""Retrieve list of establishment for collection."""
|
||||||
permission_classes = (permissions.AllowAny,)
|
permission_classes = (permissions.AllowAny,)
|
||||||
serializer_class = serializers.CollectionSerializer
|
pagination_class = ProjectPageNumberPagination
|
||||||
|
serializer_class = EstablishmentListSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
"""
|
||||||
|
Override get_queryset method.
|
||||||
|
"""
|
||||||
|
queryset = super(CollectionEstablishmentListView, self).get_queryset()
|
||||||
|
# Perform the lookup filtering.
|
||||||
|
collection = get_object_or_404(queryset, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
# CollectionItem
|
# May raise a permission denied
|
||||||
class CollectionItemListView(CollectionItemViewMixin, generics.ListAPIView):
|
self.check_object_permissions(self.request, collection)
|
||||||
"""List CollectionItem view"""
|
|
||||||
permission_classes = (permissions.AllowAny,)
|
|
||||||
serializer_class = serializers.CollectionItemSerializer
|
|
||||||
|
|
||||||
|
return collection.establishments.all()
|
||||||
class CollectionItemRetrieveView(CollectionItemViewMixin, generics.RetrieveAPIView):
|
|
||||||
"""Retrieve CollectionItem view"""
|
|
||||||
permission_classes = (permissions.AllowAny,)
|
|
||||||
serializer_class = serializers.CollectionItemSerializer
|
|
||||||
|
|
||||||
|
|
||||||
# Guide
|
# Guide
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-20 08:55
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('collection', '0009_delete_collectionitem'),
|
||||||
|
('establishment', '0023_merge_20190919_1136'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='establishment',
|
||||||
|
name='collections',
|
||||||
|
field=models.ManyToManyField(related_name='establishments', to='collection.Collection', verbose_name='Collections'),
|
||||||
|
),
|
||||||
|
]
|
||||||
14
apps/establishment/migrations/0025_merge_20190920_1012.py
Normal file
14
apps/establishment/migrations/0025_merge_20190920_1012.py
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-20 10:12
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('establishment', '0024_establishment_collections'),
|
||||||
|
('establishment', '0024_merge_20190919_1456'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-20 10:16
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('establishment', '0025_merge_20190920_1012'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='establishment',
|
||||||
|
name='preview_image_url',
|
||||||
|
field=models.URLField(blank=True, default=None, null=True, verbose_name='Preview image URL path'),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
apps/establishment/migrations/0027_auto_20190920_1120.py
Normal file
18
apps/establishment/migrations/0027_auto_20190920_1120.py
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-20 11:20
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('establishment', '0026_establishment_preview_image_url'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='establishment',
|
||||||
|
name='collections',
|
||||||
|
field=models.ManyToManyField(blank=True, default=None, null=True, related_name='establishments', to='collection.Collection', verbose_name='Collections'),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
apps/establishment/migrations/0028_auto_20190920_1205.py
Normal file
18
apps/establishment/migrations/0028_auto_20190920_1205.py
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-20 12:05
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('establishment', '0027_auto_20190920_1120'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='establishment',
|
||||||
|
name='collections',
|
||||||
|
field=models.ManyToManyField(blank=True, default=None, related_name='establishments', to='collection.Collection', verbose_name='Collections'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -124,7 +124,7 @@ class EstablishmentQuerySet(models.QuerySet):
|
||||||
"""
|
"""
|
||||||
return self.annotate(intermediate_public_mark=models.Case(
|
return self.annotate(intermediate_public_mark=models.Case(
|
||||||
models.When(
|
models.When(
|
||||||
collections__collection__collection_type=Collection.POP,
|
collections__collection_type=Collection.POP,
|
||||||
public_mark__isnull=True,
|
public_mark__isnull=True,
|
||||||
then=10
|
then=10
|
||||||
),
|
),
|
||||||
|
|
@ -164,7 +164,7 @@ class EstablishmentQuerySet(models.QuerySet):
|
||||||
"""
|
"""
|
||||||
return self.annotate(
|
return self.annotate(
|
||||||
total_mark=(models.F('distance_mark') + models.F('additional_mark')) *
|
total_mark=(models.F('distance_mark') + models.F('additional_mark')) *
|
||||||
models.F('intermediate_public_mark'))
|
models.F('intermediate_public_mark'))
|
||||||
|
|
||||||
def similar(self, establishment_pk: int):
|
def similar(self, establishment_pk: int):
|
||||||
"""
|
"""
|
||||||
|
|
@ -176,7 +176,7 @@ class EstablishmentQuerySet(models.QuerySet):
|
||||||
establishment = establishment_qs.first()
|
establishment = establishment_qs.first()
|
||||||
return self.exclude(pk=establishment_pk) \
|
return self.exclude(pk=establishment_pk) \
|
||||||
.filter(is_publish=True,
|
.filter(is_publish=True,
|
||||||
image__isnull=False,
|
image_url__isnull=False,
|
||||||
reviews__isnull=False,
|
reviews__isnull=False,
|
||||||
reviews__status=Review.READY,
|
reviews__status=Review.READY,
|
||||||
public_mark__gte=10) \
|
public_mark__gte=10) \
|
||||||
|
|
@ -269,13 +269,20 @@ class Establishment(ProjectBaseMixin, URLImageMixin, TranslatedFieldsMixin):
|
||||||
# help_text=_('Holidays closing date from'))
|
# help_text=_('Holidays closing date from'))
|
||||||
# holidays_to = models.DateTimeField(verbose_name=_('Holidays to'),
|
# holidays_to = models.DateTimeField(verbose_name=_('Holidays to'),
|
||||||
# help_text=_('Holidays closing date to'))
|
# help_text=_('Holidays closing date to'))
|
||||||
|
transportation = models.TextField(blank=True, null=True, default=None,
|
||||||
|
verbose_name=_('Transportation'))
|
||||||
|
collections = models.ManyToManyField(to='collection.Collection',
|
||||||
|
related_name='establishments',
|
||||||
|
blank=True, default=None,
|
||||||
|
verbose_name=_('Collections'))
|
||||||
|
preview_image_url = models.URLField(verbose_name=_('Preview image URL path'),
|
||||||
|
blank=True, null=True, default=None)
|
||||||
|
|
||||||
awards = generic.GenericRelation(to='main.Award')
|
awards = generic.GenericRelation(to='main.Award')
|
||||||
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')
|
||||||
transportation = models.TextField(blank=True, null=True, default=None,
|
favorites = generic.GenericRelation(to='favorites.Favorites')
|
||||||
verbose_name=_('Transportation'))
|
|
||||||
collections = generic.GenericRelation(to='collection.CollectionItem')
|
|
||||||
|
|
||||||
objects = EstablishmentQuerySet.as_manager()
|
objects = EstablishmentQuerySet.as_manager()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ from main.serializers import MetaDataContentSerializer, AwardSerializer, Currenc
|
||||||
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 django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
class ContactPhonesSerializer(serializers.ModelSerializer):
|
class ContactPhonesSerializer(serializers.ModelSerializer):
|
||||||
|
|
@ -145,7 +146,6 @@ class EstablishmentBaseSerializer(serializers.ModelSerializer):
|
||||||
subtypes = EstablishmentSubTypeSerializer(many=True)
|
subtypes = EstablishmentSubTypeSerializer(many=True)
|
||||||
address = AddressSerializer()
|
address = AddressSerializer()
|
||||||
tags = MetaDataContentSerializer(many=True)
|
tags = MetaDataContentSerializer(many=True)
|
||||||
preview_image = serializers.SerializerMethodField()
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""Meta class."""
|
"""Meta class."""
|
||||||
|
|
@ -159,28 +159,25 @@ class EstablishmentBaseSerializer(serializers.ModelSerializer):
|
||||||
'public_mark',
|
'public_mark',
|
||||||
'type',
|
'type',
|
||||||
'subtypes',
|
'subtypes',
|
||||||
'preview_image',
|
|
||||||
'address',
|
'address',
|
||||||
'tags',
|
'tags',
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_preview_image(self, obj):
|
|
||||||
"""Get preview image"""
|
|
||||||
return obj.get_full_image_url(request=self.context.get('request'),
|
|
||||||
thumbnail_key='establishment_preview')
|
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentListSerializer(EstablishmentBaseSerializer):
|
class EstablishmentListSerializer(EstablishmentBaseSerializer):
|
||||||
"""Serializer for Establishment model."""
|
"""Serializer for Establishment model."""
|
||||||
# Annotated fields
|
# Annotated fields
|
||||||
in_favorites = serializers.BooleanField(allow_null=True)
|
in_favorites = serializers.BooleanField(allow_null=True)
|
||||||
|
|
||||||
|
preview_image = serializers.URLField(source='preview_image_url')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""Meta class."""
|
"""Meta class."""
|
||||||
|
|
||||||
model = models.Establishment
|
model = models.Establishment
|
||||||
fields = EstablishmentBaseSerializer.Meta.fields + [
|
fields = EstablishmentBaseSerializer.Meta.fields + [
|
||||||
'in_favorites',
|
'in_favorites',
|
||||||
|
'preview_image',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -195,13 +192,14 @@ class EstablishmentDetailSerializer(EstablishmentListSerializer):
|
||||||
employees = EstablishmentEmployeeSerializer(source='actual_establishment_employees',
|
employees = EstablishmentEmployeeSerializer(source='actual_establishment_employees',
|
||||||
many=True)
|
many=True)
|
||||||
menu = MenuSerializers(source='menu_set', many=True, read_only=True)
|
menu = MenuSerializers(source='menu_set', many=True, read_only=True)
|
||||||
preview_image = serializers.SerializerMethodField()
|
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
in_favorites = serializers.SerializerMethodField()
|
in_favorites = serializers.SerializerMethodField()
|
||||||
|
|
||||||
|
image = serializers.URLField(source='image_url')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""Meta class."""
|
"""Meta class."""
|
||||||
|
|
||||||
|
|
@ -265,7 +263,7 @@ class EstablishmentCommentCreateSerializer(comment_serializers.CommentSerializer
|
||||||
establishment_id = self.context.get('request').parser_context.get('kwargs').get('pk')
|
establishment_id = self.context.get('request').parser_context.get('kwargs').get('pk')
|
||||||
establishment_qs = models.Establishment.objects.filter(id=establishment_id)
|
establishment_qs = models.Establishment.objects.filter(id=establishment_id)
|
||||||
if not establishment_qs.exists():
|
if not establishment_qs.exists():
|
||||||
return serializers.ValidationError()
|
raise serializers.ValidationError({'detail': _('Establishment not found.')})
|
||||||
attrs['establishment'] = establishment_qs.first()
|
attrs['establishment'] = establishment_qs.first()
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
|
|
@ -316,7 +314,7 @@ class EstablishmentFavoritesCreateSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
# Check establishment obj by pk from lookup_kwarg
|
# Check establishment obj by pk from lookup_kwarg
|
||||||
if not establishment_qs.exists():
|
if not establishment_qs.exists():
|
||||||
return serializers.ValidationError()
|
raise serializers.ValidationError({'detail': _('Object not found.')})
|
||||||
|
|
||||||
# Check existence in favorites
|
# Check existence in favorites
|
||||||
if self.get_user().favorites.by_content_type(app_label='establishment',
|
if self.get_user().favorites.by_content_type(app_label='establishment',
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,13 @@ class BaseTestCase(APITestCase):
|
||||||
self.password = 'sedragurdaredips19'
|
self.password = 'sedragurdaredips19'
|
||||||
self.email = 'sedragurda@desoz.com'
|
self.email = 'sedragurda@desoz.com'
|
||||||
self.newsletter = True
|
self.newsletter = True
|
||||||
self.user = User.objects.create_user(username=self.username, email=self.email, password=self.password)
|
self.user = User.objects.create_user(
|
||||||
|
username=self.username, email=self.email, password=self.password)
|
||||||
#get tokkens
|
#get tokkens
|
||||||
tokkens = User.create_jwt_tokens(self.user)
|
tokkens = User.create_jwt_tokens(self.user)
|
||||||
self.client.cookies = SimpleCookie({'access_token': tokkens.get('access_token'),
|
self.client.cookies = SimpleCookie(
|
||||||
'refresh_token': tokkens.get('refresh_token')})
|
{'access_token': tokkens.get('access_token'),
|
||||||
|
'refresh_token': tokkens.get('refresh_token')})
|
||||||
|
|
||||||
self.establishment_type = EstablishmentType.objects.create(name="Test establishment type")
|
self.establishment_type = EstablishmentType.objects.create(name="Test establishment type")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,5 +16,5 @@ urlpatterns = [
|
||||||
path('<int:pk>/comments/<int:comment_id>/', views.EstablishmentCommentRUDView.as_view(),
|
path('<int:pk>/comments/<int:comment_id>/', views.EstablishmentCommentRUDView.as_view(),
|
||||||
name='rud-comment'),
|
name='rud-comment'),
|
||||||
path('<int:pk>/favorites/', views.EstablishmentFavoritesCreateDestroyView.as_view(),
|
path('<int:pk>/favorites/', views.EstablishmentFavoritesCreateDestroyView.as_view(),
|
||||||
name='add-favorites')
|
name='add-to-favorites')
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -30,10 +30,13 @@ class EstablishmentSimilarListView(EstablishmentListView):
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
"""Override get_queryset method"""
|
"""Override get_queryset method"""
|
||||||
qs = super().get_queryset()
|
qs = super().get_queryset()
|
||||||
|
if not qs.filter(pk=self.kwargs.get('pk')).exists():
|
||||||
|
return qs.none()
|
||||||
return qs.similar(establishment_pk=self.kwargs.get('pk'))\
|
return qs.similar(establishment_pk=self.kwargs.get('pk'))\
|
||||||
.order_by('-total_mark')[:13]
|
.order_by('-total_mark')[:13]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentRetrieveView(EstablishmentMixin, generics.RetrieveAPIView):
|
class EstablishmentRetrieveView(EstablishmentMixin, generics.RetrieveAPIView):
|
||||||
"""Resource for getting a establishment."""
|
"""Resource for getting a establishment."""
|
||||||
serializer_class = serializers.EstablishmentDetailSerializer
|
serializer_class = serializers.EstablishmentDetailSerializer
|
||||||
|
|
@ -76,14 +79,6 @@ class EstablishmentCommentRUDView(generics.RetrieveUpdateDestroyAPIView):
|
||||||
Returns the object the view is displaying.
|
Returns the object the view is displaying.
|
||||||
"""
|
"""
|
||||||
queryset = self.filter_queryset(self.get_queryset())
|
queryset = self.filter_queryset(self.get_queryset())
|
||||||
lookup_url_kwargs = ('pk', 'comment_id')
|
|
||||||
|
|
||||||
assert lookup_url_kwargs not in self.kwargs.keys(), (
|
|
||||||
'Expected view %s to be called with a URL keyword argument '
|
|
||||||
'named "%s". Fix your URL conf, or set the `.lookup_field` '
|
|
||||||
'attribute on the view correctly.' %
|
|
||||||
(self.__class__.__name__, lookup_url_kwargs)
|
|
||||||
)
|
|
||||||
|
|
||||||
establishment_obj = get_object_or_404(queryset,
|
establishment_obj = get_object_or_404(queryset,
|
||||||
pk=self.kwargs['pk'])
|
pk=self.kwargs['pk'])
|
||||||
|
|
@ -104,17 +99,8 @@ class EstablishmentFavoritesCreateDestroyView(generics.CreateAPIView, generics.D
|
||||||
"""
|
"""
|
||||||
Returns the object the view is displaying.
|
Returns the object the view is displaying.
|
||||||
"""
|
"""
|
||||||
lookup_url_kwargs = ('pk',)
|
|
||||||
assert lookup_url_kwargs not in self.kwargs.keys(), (
|
|
||||||
'Expected view %s to be called with a URL keyword argument '
|
|
||||||
'named "%s". Fix your URL conf, or set the `.lookup_field` '
|
|
||||||
'attribute on the view correctly.' %
|
|
||||||
(self.__class__.__name__, lookup_url_kwargs)
|
|
||||||
)
|
|
||||||
|
|
||||||
obj = get_object_or_404(
|
obj = get_object_or_404(
|
||||||
self.request.user.favorites.by_user(user=self.request.user)
|
self.request.user.favorites.by_content_type(app_label='establishment',
|
||||||
.by_content_type(app_label='establishment',
|
|
||||||
model='establishment')
|
model='establishment')
|
||||||
.by_object_id(object_id=self.kwargs['pk']))
|
.by_object_id(object_id=self.kwargs['pk']))
|
||||||
# May raise a permission denied
|
# May raise a permission denied
|
||||||
|
|
@ -162,15 +148,6 @@ class EstablishmentScheduleRUDView(generics.RetrieveUpdateDestroyAPIView):
|
||||||
"""
|
"""
|
||||||
Returns the object the view is displaying.
|
Returns the object the view is displaying.
|
||||||
"""
|
"""
|
||||||
lookup_url_kwargs = ('pk', 'schedule_id')
|
|
||||||
|
|
||||||
assert lookup_url_kwargs not in self.kwargs.keys(), (
|
|
||||||
'Expected view %s to be called with a URL keyword argument '
|
|
||||||
'named "%s". Fix your URL conf, or set the `.lookup_field` '
|
|
||||||
'attribute on the view correctly.' %
|
|
||||||
(self.__class__.__name__, lookup_url_kwargs)
|
|
||||||
)
|
|
||||||
|
|
||||||
establishment_pk = self.kwargs['pk']
|
establishment_pk = self.kwargs['pk']
|
||||||
schedule_id = self.kwargs['schedule_id']
|
schedule_id = self.kwargs['schedule_id']
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,3 @@
|
||||||
from .models import Favorites
|
from .models import Favorites
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from establishment.serializers import EstablishmentBaseSerializer
|
from establishment.serializers import EstablishmentBaseSerializer
|
||||||
|
|
||||||
|
|
||||||
class FavoritesEstablishmentListSerializer(serializers.ModelSerializer):
|
|
||||||
"""Serializer for model Favorites"""
|
|
||||||
detail = EstablishmentBaseSerializer(source='content_object')
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
"""Meta class."""
|
|
||||||
model = Favorites
|
|
||||||
fields = (
|
|
||||||
'id',
|
|
||||||
'detail',
|
|
||||||
)
|
|
||||||
|
|
|
||||||
|
|
@ -8,5 +8,4 @@ app_name = 'favorites'
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('establishments/', views.FavoritesEstablishmentListView.as_view(),
|
path('establishments/', views.FavoritesEstablishmentListView.as_view(),
|
||||||
name='establishment-list'),
|
name='establishment-list'),
|
||||||
path('remove/<int:pk>/', views.FavoritesDestroyView.as_view(), name='remove-from-favorites'),
|
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
"""Views for app favorites."""
|
"""Views for app favorites."""
|
||||||
from rest_framework import generics
|
from rest_framework import generics
|
||||||
from .serializers import FavoritesEstablishmentListSerializer
|
|
||||||
|
from establishment.models import Establishment
|
||||||
|
from establishment.serializers import EstablishmentListSerializer
|
||||||
from .models import Favorites
|
from .models import Favorites
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -11,15 +13,10 @@ class FavoritesBaseView(generics.GenericAPIView):
|
||||||
return Favorites.objects.by_user(self.request.user)
|
return Favorites.objects.by_user(self.request.user)
|
||||||
|
|
||||||
|
|
||||||
class FavoritesEstablishmentListView(FavoritesBaseView, generics.ListAPIView):
|
class FavoritesEstablishmentListView(generics.ListAPIView):
|
||||||
"""List views for favorites"""
|
"""List views for favorites"""
|
||||||
serializer_class = FavoritesEstablishmentListSerializer
|
serializer_class = EstablishmentListSerializer
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
"""Override get_queryset method"""
|
"""Override get_queryset method"""
|
||||||
return super().get_queryset().by_content_type(app_label='establishment',
|
return Establishment.objects.filter(favorites__user=self.request.user)
|
||||||
model='establishment')
|
|
||||||
|
|
||||||
|
|
||||||
class FavoritesDestroyView(FavoritesBaseView, generics.DestroyAPIView):
|
|
||||||
"""Destroy view for favorites"""
|
|
||||||
|
|
|
||||||
|
|
@ -333,11 +333,9 @@ class Carousel(models.Model):
|
||||||
return self.content_object.public_mark
|
return self.content_object.public_mark
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def image(self):
|
def image_url(self):
|
||||||
if hasattr(self.content_object.image, 'url'):
|
if hasattr(self.content_object, 'image_url'):
|
||||||
return self.content_object.image
|
return self.content_object.image_url
|
||||||
if hasattr(self.content_object.image.image, 'url'):
|
|
||||||
return self.content_object.image.image
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def model_name(self):
|
def model_name(self):
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ class CarouselListSerializer(serializers.ModelSerializer):
|
||||||
name = serializers.CharField()
|
name = serializers.CharField()
|
||||||
toque_number = serializers.CharField()
|
toque_number = serializers.CharField()
|
||||||
public_mark = serializers.CharField()
|
public_mark = serializers.CharField()
|
||||||
image = serializers.ImageField()
|
image = serializers.URLField(source='image_url')
|
||||||
awards = AwardBaseSerializer(many=True)
|
awards = AwardBaseSerializer(many=True)
|
||||||
vintage_year = serializers.IntegerField()
|
vintage_year = serializers.IntegerField()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,12 +68,13 @@ class EstablishmentDocument(Document):
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
collections = fields.ObjectField(
|
# todo: need to fix
|
||||||
properties={
|
# collections = fields.ObjectField(
|
||||||
'id': fields.IntegerField(attr='collection.id'),
|
# properties={
|
||||||
'collection_type': fields.IntegerField(attr='collection.collection_type'),
|
# 'id': fields.IntegerField(attr='collection.id'),
|
||||||
},
|
# 'collection_type': fields.IntegerField(attr='collection.collection_type'),
|
||||||
multi=True)
|
# },
|
||||||
|
# multi=True)
|
||||||
|
|
||||||
class Django:
|
class Django:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,3 +46,11 @@ class NewsDocument(Document):
|
||||||
|
|
||||||
def prepare_description(self, instance):
|
def prepare_description(self, instance):
|
||||||
return instance.description
|
return instance.description
|
||||||
|
|
||||||
|
def get_instances_from_related(self, related_instance):
|
||||||
|
"""If related_models is set, define how to retrieve the Car instance(s) from the related model.
|
||||||
|
The related_models option should be used with caution because it can lead in the index
|
||||||
|
to the updating of a lot of items.
|
||||||
|
"""
|
||||||
|
if isinstance(related_instance, models.NewsType):
|
||||||
|
return related_instance.news_set.all()
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ app_name = 'web'
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('account/', include('account.urls.web')),
|
path('account/', include('account.urls.web')),
|
||||||
path('re_blocks/', include('advertisement.urls.web')),
|
path('re_blocks/', include('advertisement.urls.web')),
|
||||||
path('collection/', include('collection.urls.web')),
|
path('collections/', include('collection.urls.web')),
|
||||||
path('establishments/', include('establishment.urls.web')),
|
path('establishments/', include('establishment.urls.web')),
|
||||||
path('news/', include('news.urls.web')),
|
path('news/', include('news.urls.web')),
|
||||||
path('notifications/', include('notification.urls.web')),
|
path('notifications/', include('notification.urls.web')),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user