From 413c93bead79dd59924a0dac697d151849fafcb4 Mon Sep 17 00:00:00 2001 From: Anatoly Date: Fri, 20 Sep 2019 13:35:59 +0300 Subject: [PATCH 1/6] fixed problem with image, refactored favorites, collection --- apps/collection/admin.py | 5 --- .../migrations/0009_delete_collectionitem.py | 16 +++++++ .../migrations/0010_collection_description.py | 19 ++++++++ apps/collection/models.py | 28 +++--------- apps/collection/serializers/common.py | 14 +----- apps/collection/urls/common.py | 7 +-- apps/collection/views/common.py | 44 +++++++++++-------- .../0024_establishment_collections.py | 19 ++++++++ .../migrations/0025_merge_20190920_1012.py | 14 ++++++ .../0026_establishment_preview_image_url.py | 18 ++++++++ apps/establishment/models.py | 18 +++++--- apps/establishment/serializers/common.py | 15 +++---- apps/establishment/urls/common.py | 2 +- apps/establishment/views/web.py | 16 ++++--- apps/favorites/serializers.py | 13 ------ apps/favorites/urls.py | 1 - apps/favorites/views.py | 15 +++---- apps/main/models.py | 8 ++-- apps/main/serializers.py | 4 +- .../search_indexes/documents/establishment.py | 13 +++--- 20 files changed, 166 insertions(+), 123 deletions(-) create mode 100644 apps/collection/migrations/0009_delete_collectionitem.py create mode 100644 apps/collection/migrations/0010_collection_description.py create mode 100644 apps/establishment/migrations/0024_establishment_collections.py create mode 100644 apps/establishment/migrations/0025_merge_20190920_1012.py create mode 100644 apps/establishment/migrations/0026_establishment_preview_image_url.py diff --git a/apps/collection/admin.py b/apps/collection/admin.py index 3d0a8e3c..2e2c22e2 100644 --- a/apps/collection/admin.py +++ b/apps/collection/admin.py @@ -8,11 +8,6 @@ class CollectionAdmin(admin.ModelAdmin): """Collection admin.""" -@admin.register(models.CollectionItem) -class CollectionItemAdmin(admin.ModelAdmin): - """CollectionItem admin.""" - - @admin.register(models.Guide) class GuideAdmin(admin.ModelAdmin): """Guide admin.""" diff --git a/apps/collection/migrations/0009_delete_collectionitem.py b/apps/collection/migrations/0009_delete_collectionitem.py new file mode 100644 index 00000000..ea8fca72 --- /dev/null +++ b/apps/collection/migrations/0009_delete_collectionitem.py @@ -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', + ), + ] diff --git a/apps/collection/migrations/0010_collection_description.py b/apps/collection/migrations/0010_collection_description.py new file mode 100644 index 00000000..b66d8156 --- /dev/null +++ b/apps/collection/migrations/0010_collection_description.py @@ -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'), + ), + ] diff --git a/apps/collection/models.py b/apps/collection/models.py index 3ef4d0bf..50af7ec7 100644 --- a/apps/collection/models.py +++ b/apps/collection/models.py @@ -1,10 +1,11 @@ from django.contrib.postgres.fields import JSONField 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.utils.translation import gettext_lazy as _ from utils.models import ProjectBaseMixin, ImageMixin +from utils.models import TranslatedFieldsMixin # Mixins @@ -40,7 +41,7 @@ class CollectionQuerySet(models.QuerySet): return self.filter(is_publish=True) -class Collection(ProjectBaseMixin, CollectionNameMixin, CollectionDateMixin): +class Collection(ProjectBaseMixin, CollectionNameMixin, CollectionDateMixin, TranslatedFieldsMixin): """Collection model.""" ORDINARY = 0 # Ordinary collection POP = 1 # POP collection @@ -65,6 +66,9 @@ class Collection(ProjectBaseMixin, CollectionNameMixin, CollectionDateMixin): block_size = JSONField( _('collection block properties'), null=True, blank=True, 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() @@ -78,26 +82,6 @@ class Collection(ProjectBaseMixin, CollectionNameMixin, CollectionDateMixin): 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): """QuerySet for Guide.""" diff --git a/apps/collection/serializers/common.py b/apps/collection/serializers/common.py index 87bf7802..5e0029ee 100644 --- a/apps/collection/serializers/common.py +++ b/apps/collection/serializers/common.py @@ -9,6 +9,7 @@ class CollectionSerializer(serializers.ModelSerializer): """Collection serializer""" # RESPONSE image_url = serializers.ImageField(source='image.image') + description_translated = serializers.CharField(read_only=True, allow_null=True) # COMMON block_size = serializers.JSONField() @@ -30,6 +31,7 @@ class CollectionSerializer(serializers.ModelSerializer): fields = [ 'id', 'name', + 'description_translated', 'start', 'end', 'image', @@ -41,18 +43,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): """Guide serializer""" class Meta: diff --git a/apps/collection/urls/common.py b/apps/collection/urls/common.py index 4396bff4..41414a10 100644 --- a/apps/collection/urls/common.py +++ b/apps/collection/urls/common.py @@ -7,11 +7,8 @@ app_name = 'collection' urlpatterns = [ path('', views.CollectionListView.as_view(), name='list'), - path('/', views.CollectionRetrieveView.as_view(), name='detail'), - - path('items/', views.CollectionItemListView.as_view(), name='collection-items-list'), - path('items//', views.CollectionItemRetrieveView.as_view(), - name='collection-items-detail'), + path('/establishments/', views.CollectionEstablishmentListView.as_view(), + name='detail'), path('guides/', views.GuideListView.as_view(), name='guides-list'), path('guides//', views.GuideRetrieveView.as_view(), name='guides-detail'), diff --git a/apps/collection/views/common.py b/apps/collection/views/common.py index af7c4849..8c386930 100644 --- a/apps/collection/views/common.py +++ b/apps/collection/views/common.py @@ -2,6 +2,9 @@ from rest_framework import generics 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 collection.serializers import common as serializers @@ -12,12 +15,6 @@ class CollectionViewMixin(generics.GenericAPIView): 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): """Mixin for Guide view""" model = models.Guide @@ -28,7 +25,6 @@ class GuideViewMixin(generics.GenericAPIView): # Collections class CollectionListView(CollectionViewMixin, generics.ListAPIView): """List Collection view""" - pagination_class = None permission_classes = (permissions.AllowAny,) serializer_class = serializers.CollectionSerializer @@ -39,23 +35,33 @@ class CollectionListView(CollectionViewMixin, generics.ListAPIView): .order_by('-on_top', '-created') -class CollectionRetrieveView(CollectionViewMixin, generics.RetrieveAPIView): - """Retrieve Collection view""" +class CollectionEstablishmentListView(CollectionListView): + """Retrieve list of establishment for collection.""" 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. + lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field -# CollectionItem -class CollectionItemListView(CollectionItemViewMixin, generics.ListAPIView): - """List CollectionItem view""" - permission_classes = (permissions.AllowAny,) - serializer_class = serializers.CollectionItemSerializer + assert lookup_url_kwarg in self.kwargs, ( + '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_kwarg) + ) + collection = get_object_or_404(queryset, pk=self.kwargs['pk']) -class CollectionItemRetrieveView(CollectionItemViewMixin, generics.RetrieveAPIView): - """Retrieve CollectionItem view""" - permission_classes = (permissions.AllowAny,) - serializer_class = serializers.CollectionItemSerializer + # May raise a permission denied + self.check_object_permissions(self.request, collection) + + return collection.establishments.all() # Guide diff --git a/apps/establishment/migrations/0024_establishment_collections.py b/apps/establishment/migrations/0024_establishment_collections.py new file mode 100644 index 00000000..b801ce3d --- /dev/null +++ b/apps/establishment/migrations/0024_establishment_collections.py @@ -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'), + ), + ] diff --git a/apps/establishment/migrations/0025_merge_20190920_1012.py b/apps/establishment/migrations/0025_merge_20190920_1012.py new file mode 100644 index 00000000..b8821b76 --- /dev/null +++ b/apps/establishment/migrations/0025_merge_20190920_1012.py @@ -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 = [ + ] diff --git a/apps/establishment/migrations/0026_establishment_preview_image_url.py b/apps/establishment/migrations/0026_establishment_preview_image_url.py new file mode 100644 index 00000000..c398737e --- /dev/null +++ b/apps/establishment/migrations/0026_establishment_preview_image_url.py @@ -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'), + ), + ] diff --git a/apps/establishment/models.py b/apps/establishment/models.py index 298b32ff..2841301f 100644 --- a/apps/establishment/models.py +++ b/apps/establishment/models.py @@ -124,7 +124,7 @@ class EstablishmentQuerySet(models.QuerySet): """ return self.annotate(intermediate_public_mark=models.Case( models.When( - collections__collection__collection_type=Collection.POP, + collections__collection_type=Collection.POP, public_mark__isnull=True, then=10 ), @@ -164,7 +164,7 @@ class EstablishmentQuerySet(models.QuerySet): """ return self.annotate( 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): """ @@ -176,7 +176,7 @@ class EstablishmentQuerySet(models.QuerySet): establishment = establishment_qs.first() return self.exclude(pk=establishment_pk) \ .filter(is_publish=True, - image__isnull=False, + image_url__isnull=False, reviews__isnull=False, reviews__status=Review.READY, public_mark__gte=10) \ @@ -269,13 +269,19 @@ class Establishment(ProjectBaseMixin, URLImageMixin, TranslatedFieldsMixin): # help_text=_('Holidays closing date from')) # holidays_to = models.DateTimeField(verbose_name=_('Holidays 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', + verbose_name=_('Collections'), + related_name='establishments') + preview_image_url = models.URLField(verbose_name=_('Preview image URL path'), + blank=True, null=True, default=None) + awards = generic.GenericRelation(to='main.Award') tags = generic.GenericRelation(to='main.MetaDataContent') reviews = generic.GenericRelation(to='review.Review') comments = generic.GenericRelation(to='comment.Comment') - transportation = models.TextField(blank=True, null=True, default=None, - verbose_name=_('Transportation')) - collections = generic.GenericRelation(to='collection.CollectionItem') + favorites = generic.GenericRelation(to='favorites.Favorites') objects = EstablishmentQuerySet.as_manager() diff --git a/apps/establishment/serializers/common.py b/apps/establishment/serializers/common.py index 956130d6..79075fcf 100644 --- a/apps/establishment/serializers/common.py +++ b/apps/establishment/serializers/common.py @@ -11,6 +11,7 @@ from main.serializers import MetaDataContentSerializer, AwardSerializer, Currenc from review import models as review_models from timetable.serialziers import ScheduleRUDSerializer from utils import exceptions as utils_exceptions +from django.utils.translation import gettext_lazy as _ class ContactPhonesSerializer(serializers.ModelSerializer): @@ -145,7 +146,6 @@ class EstablishmentBaseSerializer(serializers.ModelSerializer): subtypes = EstablishmentSubTypeSerializer(many=True) address = AddressSerializer() tags = MetaDataContentSerializer(many=True) - preview_image = serializers.SerializerMethodField() class Meta: """Meta class.""" @@ -159,16 +159,11 @@ class EstablishmentBaseSerializer(serializers.ModelSerializer): 'public_mark', 'type', 'subtypes', - 'preview_image', 'address', 'tags', + 'image_url', ] - 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): """Serializer for Establishment model.""" @@ -181,6 +176,7 @@ class EstablishmentListSerializer(EstablishmentBaseSerializer): model = models.Establishment fields = EstablishmentBaseSerializer.Meta.fields + [ 'in_favorites', + 'preview_image_url', ] @@ -195,7 +191,6 @@ class EstablishmentDetailSerializer(EstablishmentListSerializer): employees = EstablishmentEmployeeSerializer(source='actual_establishment_employees', many=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_carte = serializers.DecimalField(max_digits=14, decimal_places=2, read_only=True) @@ -209,7 +204,7 @@ class EstablishmentDetailSerializer(EstablishmentListSerializer): fields = EstablishmentListSerializer.Meta.fields + [ 'description_translated', 'price_level', - 'image', + 'image_url', 'awards', 'schedule', 'website', @@ -316,7 +311,7 @@ class EstablishmentFavoritesCreateSerializer(serializers.ModelSerializer): # Check establishment obj by pk from lookup_kwarg if not establishment_qs.exists(): - return serializers.ValidationError() + raise serializers.ValidationError({'detail': _('Object not found.')}) # Check existence in favorites if self.get_user().favorites.by_content_type(app_label='establishment', diff --git a/apps/establishment/urls/common.py b/apps/establishment/urls/common.py index 3fdd46d3..1d1379ee 100644 --- a/apps/establishment/urls/common.py +++ b/apps/establishment/urls/common.py @@ -16,5 +16,5 @@ urlpatterns = [ path('/comments//', views.EstablishmentCommentRUDView.as_view(), name='rud-comment'), path('/favorites/', views.EstablishmentFavoritesCreateDestroyView.as_view(), - name='add-favorites') + name='add-to-favorites') ] diff --git a/apps/establishment/views/web.py b/apps/establishment/views/web.py index 73c1621d..daa26d6a 100644 --- a/apps/establishment/views/web.py +++ b/apps/establishment/views/web.py @@ -30,10 +30,13 @@ class EstablishmentSimilarListView(EstablishmentListView): def get_queryset(self): """Override get_queryset method""" 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'))\ .order_by('-total_mark')[:13] + class EstablishmentRetrieveView(EstablishmentMixin, generics.RetrieveAPIView): """Resource for getting a establishment.""" serializer_class = serializers.EstablishmentDetailSerializer @@ -78,7 +81,7 @@ class EstablishmentCommentRUDView(generics.RetrieveUpdateDestroyAPIView): queryset = self.filter_queryset(self.get_queryset()) lookup_url_kwargs = ('pk', 'comment_id') - assert lookup_url_kwargs not in self.kwargs.keys(), ( + assert lookup_url_kwargs 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.' % @@ -104,17 +107,16 @@ class EstablishmentFavoritesCreateDestroyView(generics.CreateAPIView, generics.D """ Returns the object the view is displaying. """ - lookup_url_kwargs = ('pk',) - assert lookup_url_kwargs not in self.kwargs.keys(), ( + lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field + assert lookup_url_kwarg in self.kwargs, ( '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) + (self.__class__.__name__, lookup_url_kwarg) ) obj = get_object_or_404( - self.request.user.favorites.by_user(user=self.request.user) - .by_content_type(app_label='establishment', + self.request.user.favorites.by_content_type(app_label='establishment', model='establishment') .by_object_id(object_id=self.kwargs['pk'])) # May raise a permission denied @@ -164,7 +166,7 @@ class EstablishmentScheduleRUDView(generics.RetrieveUpdateDestroyAPIView): """ lookup_url_kwargs = ('pk', 'schedule_id') - assert lookup_url_kwargs not in self.kwargs.keys(), ( + assert lookup_url_kwargs 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.' % diff --git a/apps/favorites/serializers.py b/apps/favorites/serializers.py index d4485c54..bf0db4fb 100644 --- a/apps/favorites/serializers.py +++ b/apps/favorites/serializers.py @@ -2,16 +2,3 @@ from .models import Favorites from rest_framework import serializers 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', - ) diff --git a/apps/favorites/urls.py b/apps/favorites/urls.py index 80498e65..bd0c1d16 100644 --- a/apps/favorites/urls.py +++ b/apps/favorites/urls.py @@ -8,5 +8,4 @@ app_name = 'favorites' urlpatterns = [ path('establishments/', views.FavoritesEstablishmentListView.as_view(), name='establishment-list'), - path('remove//', views.FavoritesDestroyView.as_view(), name='remove-from-favorites'), ] diff --git a/apps/favorites/views.py b/apps/favorites/views.py index c35edcf5..aed11709 100644 --- a/apps/favorites/views.py +++ b/apps/favorites/views.py @@ -1,6 +1,8 @@ """Views for app favorites.""" from rest_framework import generics -from .serializers import FavoritesEstablishmentListSerializer + +from establishment.models import Establishment +from establishment.serializers import EstablishmentListSerializer from .models import Favorites @@ -11,15 +13,10 @@ class FavoritesBaseView(generics.GenericAPIView): return Favorites.objects.by_user(self.request.user) -class FavoritesEstablishmentListView(FavoritesBaseView, generics.ListAPIView): +class FavoritesEstablishmentListView(generics.ListAPIView): """List views for favorites""" - serializer_class = FavoritesEstablishmentListSerializer + serializer_class = EstablishmentListSerializer def get_queryset(self): """Override get_queryset method""" - return super().get_queryset().by_content_type(app_label='establishment', - model='establishment') - - -class FavoritesDestroyView(FavoritesBaseView, generics.DestroyAPIView): - """Destroy view for favorites""" + return Establishment.objects.filter(favorites__user=self.request.user) diff --git a/apps/main/models.py b/apps/main/models.py index fcf8667b..47ac90be 100644 --- a/apps/main/models.py +++ b/apps/main/models.py @@ -333,11 +333,9 @@ class Carousel(models.Model): return self.content_object.public_mark @property - def image(self): - if hasattr(self.content_object.image, 'url'): - return self.content_object.image - if hasattr(self.content_object.image.image, 'url'): - return self.content_object.image.image + def image_url(self): + if hasattr(self.content_object, 'image_url'): + return self.content_object.image_url @property def model_name(self): diff --git a/apps/main/serializers.py b/apps/main/serializers.py index 607e3a30..d04335f9 100644 --- a/apps/main/serializers.py +++ b/apps/main/serializers.py @@ -138,7 +138,7 @@ class CarouselListSerializer(serializers.ModelSerializer): name = serializers.CharField() toque_number = serializers.CharField() public_mark = serializers.CharField() - image = serializers.ImageField() + image_url = serializers.URLField() awards = AwardBaseSerializer(many=True) vintage_year = serializers.IntegerField() @@ -152,7 +152,7 @@ class CarouselListSerializer(serializers.ModelSerializer): 'awards', 'toque_number', 'public_mark', - 'image', + 'image_url', 'vintage_year', ] diff --git a/apps/search_indexes/documents/establishment.py b/apps/search_indexes/documents/establishment.py index 8c96066e..10f95d6c 100644 --- a/apps/search_indexes/documents/establishment.py +++ b/apps/search_indexes/documents/establishment.py @@ -68,12 +68,13 @@ class EstablishmentDocument(Document): ), } ) - collections = fields.ObjectField( - properties={ - 'id': fields.IntegerField(attr='collection.id'), - 'collection_type': fields.IntegerField(attr='collection.collection_type'), - }, - multi=True) + # todo: need to fix + # collections = fields.ObjectField( + # properties={ + # 'id': fields.IntegerField(attr='collection.id'), + # 'collection_type': fields.IntegerField(attr='collection.collection_type'), + # }, + # multi=True) class Django: From 2089ca067a0ca0ede2344a04ee9a16f04935dc9e Mon Sep 17 00:00:00 2001 From: Anatoly Date: Fri, 20 Sep 2019 14:22:39 +0300 Subject: [PATCH 2/6] chane FK to URLField in Collection model, added properties to field collections in Establishment model --- .../migrations/0011_auto_20190920_1059.py | 22 +++++++++++++++++++ apps/collection/models.py | 8 +++---- apps/collection/serializers/common.py | 6 ----- .../migrations/0027_auto_20190920_1120.py | 18 +++++++++++++++ apps/establishment/models.py | 5 +++-- 5 files changed, 46 insertions(+), 13 deletions(-) create mode 100644 apps/collection/migrations/0011_auto_20190920_1059.py create mode 100644 apps/establishment/migrations/0027_auto_20190920_1120.py diff --git a/apps/collection/migrations/0011_auto_20190920_1059.py b/apps/collection/migrations/0011_auto_20190920_1059.py new file mode 100644 index 00000000..ac3c21c5 --- /dev/null +++ b/apps/collection/migrations/0011_auto_20190920_1059.py @@ -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'), + ), + ] diff --git a/apps/collection/models.py b/apps/collection/models.py index 50af7ec7..a4a9bcae 100644 --- a/apps/collection/models.py +++ b/apps/collection/models.py @@ -4,7 +4,7 @@ from utils.models import TJSONField from django.db import models 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 @@ -41,7 +41,8 @@ class CollectionQuerySet(models.QuerySet): return self.filter(is_publish=True) -class Collection(ProjectBaseMixin, CollectionNameMixin, CollectionDateMixin, TranslatedFieldsMixin): +class Collection(ProjectBaseMixin, CollectionNameMixin, CollectionDateMixin, + TranslatedFieldsMixin, URLImageMixin): """Collection model.""" ORDINARY = 0 # Ordinary collection POP = 1 # POP collection @@ -54,9 +55,6 @@ class Collection(ProjectBaseMixin, CollectionNameMixin, CollectionDateMixin, Tra collection_type = models.PositiveSmallIntegerField(choices=COLLECTION_TYPES, default=ORDINARY, 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( default=False, verbose_name=_('Publish status')) on_top = models.BooleanField( diff --git a/apps/collection/serializers/common.py b/apps/collection/serializers/common.py index 5e0029ee..85d66d30 100644 --- a/apps/collection/serializers/common.py +++ b/apps/collection/serializers/common.py @@ -1,14 +1,12 @@ from rest_framework import serializers from collection import models -from gallery import models as gallery_models from location import models as location_models class CollectionSerializer(serializers.ModelSerializer): """Collection serializer""" # RESPONSE - image_url = serializers.ImageField(source='image.image') description_translated = serializers.CharField(read_only=True, allow_null=True) # COMMON @@ -22,9 +20,6 @@ class CollectionSerializer(serializers.ModelSerializer): country = serializers.PrimaryKeyRelatedField( queryset=location_models.Country.objects.all(), write_only=True) - image = serializers.PrimaryKeyRelatedField( - queryset=gallery_models.Image.objects.all(), - write_only=True) class Meta: model = models.Collection @@ -34,7 +29,6 @@ class CollectionSerializer(serializers.ModelSerializer): 'description_translated', 'start', 'end', - 'image', 'image_url', 'is_publish', 'on_top', diff --git a/apps/establishment/migrations/0027_auto_20190920_1120.py b/apps/establishment/migrations/0027_auto_20190920_1120.py new file mode 100644 index 00000000..974b8093 --- /dev/null +++ b/apps/establishment/migrations/0027_auto_20190920_1120.py @@ -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'), + ), + ] diff --git a/apps/establishment/models.py b/apps/establishment/models.py index 2841301f..f731cd74 100644 --- a/apps/establishment/models.py +++ b/apps/establishment/models.py @@ -272,8 +272,9 @@ class Establishment(ProjectBaseMixin, URLImageMixin, TranslatedFieldsMixin): transportation = models.TextField(blank=True, null=True, default=None, verbose_name=_('Transportation')) collections = models.ManyToManyField(to='collection.Collection', - verbose_name=_('Collections'), - related_name='establishments') + related_name='establishments', + blank=True, null=True, default=None, + verbose_name=_('Collections')) preview_image_url = models.URLField(verbose_name=_('Preview image URL path'), blank=True, null=True, default=None) From 09c9d666b57b93fca68826a537fbf973e71a2a8e Mon Sep 17 00:00:00 2001 From: Anatoly Date: Fri, 20 Sep 2019 14:42:34 +0300 Subject: [PATCH 3/6] rename image_url to image, preview_image_url to preview_image --- apps/establishment/serializers/common.py | 9 ++++++--- apps/main/serializers.py | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/apps/establishment/serializers/common.py b/apps/establishment/serializers/common.py index 79075fcf..56583ba2 100644 --- a/apps/establishment/serializers/common.py +++ b/apps/establishment/serializers/common.py @@ -161,7 +161,6 @@ class EstablishmentBaseSerializer(serializers.ModelSerializer): 'subtypes', 'address', 'tags', - 'image_url', ] @@ -170,13 +169,15 @@ class EstablishmentListSerializer(EstablishmentBaseSerializer): # Annotated fields in_favorites = serializers.BooleanField(allow_null=True) + preview_image = serializers.URLField(source='preview_image_url') + class Meta: """Meta class.""" model = models.Establishment fields = EstablishmentBaseSerializer.Meta.fields + [ 'in_favorites', - 'preview_image_url', + 'preview_image', ] @@ -197,6 +198,8 @@ class EstablishmentDetailSerializer(EstablishmentListSerializer): in_favorites = serializers.SerializerMethodField() + image = serializers.URLField(source='image_url') + class Meta: """Meta class.""" @@ -204,7 +207,7 @@ class EstablishmentDetailSerializer(EstablishmentListSerializer): fields = EstablishmentListSerializer.Meta.fields + [ 'description_translated', 'price_level', - 'image_url', + 'image', 'awards', 'schedule', 'website', diff --git a/apps/main/serializers.py b/apps/main/serializers.py index d04335f9..f2beb768 100644 --- a/apps/main/serializers.py +++ b/apps/main/serializers.py @@ -138,7 +138,7 @@ class CarouselListSerializer(serializers.ModelSerializer): name = serializers.CharField() toque_number = serializers.CharField() public_mark = serializers.CharField() - image_url = serializers.URLField() + image = serializers.URLField(source='image_url') awards = AwardBaseSerializer(many=True) vintage_year = serializers.IntegerField() @@ -152,7 +152,7 @@ class CarouselListSerializer(serializers.ModelSerializer): 'awards', 'toque_number', 'public_mark', - 'image_url', + 'image', 'vintage_year', ] From 5f3947601a7c2f919aa7802bb1f72b9bf39f8837 Mon Sep 17 00:00:00 2001 From: Anatoly Date: Fri, 20 Sep 2019 15:11:33 +0300 Subject: [PATCH 4/6] rename url path collection to collections, delete property in M2M field --- .../migrations/0028_auto_20190920_1205.py | 18 ++++++++++++++++++ apps/establishment/models.py | 2 +- project/urls/web.py | 2 +- 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 apps/establishment/migrations/0028_auto_20190920_1205.py diff --git a/apps/establishment/migrations/0028_auto_20190920_1205.py b/apps/establishment/migrations/0028_auto_20190920_1205.py new file mode 100644 index 00000000..abdd4d7f --- /dev/null +++ b/apps/establishment/migrations/0028_auto_20190920_1205.py @@ -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'), + ), + ] diff --git a/apps/establishment/models.py b/apps/establishment/models.py index f731cd74..042c25e0 100644 --- a/apps/establishment/models.py +++ b/apps/establishment/models.py @@ -273,7 +273,7 @@ class Establishment(ProjectBaseMixin, URLImageMixin, TranslatedFieldsMixin): verbose_name=_('Transportation')) collections = models.ManyToManyField(to='collection.Collection', related_name='establishments', - blank=True, null=True, default=None, + blank=True, default=None, verbose_name=_('Collections')) preview_image_url = models.URLField(verbose_name=_('Preview image URL path'), blank=True, null=True, default=None) diff --git a/project/urls/web.py b/project/urls/web.py index 18bb8fd9..0a81672d 100644 --- a/project/urls/web.py +++ b/project/urls/web.py @@ -20,7 +20,7 @@ app_name = 'web' urlpatterns = [ path('account/', include('account.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('news/', include('news.urls.web')), path('notifications/', include('notification.urls.web')), From 193ecfba7a4a7ea22e07d70683f8fde8c7aea80e Mon Sep 17 00:00:00 2001 From: Anatoly Date: Fri, 20 Sep 2019 15:38:20 +0300 Subject: [PATCH 5/6] fixed comments --- apps/collection/views/common.py | 9 --------- apps/establishment/serializers/common.py | 2 +- apps/establishment/views/web.py | 25 ------------------------ 3 files changed, 1 insertion(+), 35 deletions(-) diff --git a/apps/collection/views/common.py b/apps/collection/views/common.py index 8c386930..8d2eb109 100644 --- a/apps/collection/views/common.py +++ b/apps/collection/views/common.py @@ -47,15 +47,6 @@ class CollectionEstablishmentListView(CollectionListView): """ queryset = super(CollectionEstablishmentListView, self).get_queryset() # Perform the lookup filtering. - lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field - - assert lookup_url_kwarg in self.kwargs, ( - '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_kwarg) - ) - collection = get_object_or_404(queryset, pk=self.kwargs['pk']) # May raise a permission denied diff --git a/apps/establishment/serializers/common.py b/apps/establishment/serializers/common.py index 56583ba2..65522942 100644 --- a/apps/establishment/serializers/common.py +++ b/apps/establishment/serializers/common.py @@ -263,7 +263,7 @@ class EstablishmentCommentCreateSerializer(comment_serializers.CommentSerializer establishment_id = self.context.get('request').parser_context.get('kwargs').get('pk') establishment_qs = models.Establishment.objects.filter(id=establishment_id) if not establishment_qs.exists(): - return serializers.ValidationError() + raise serializers.ValidationError({'detail': _('Establishment not found.')}) attrs['establishment'] = establishment_qs.first() return attrs diff --git a/apps/establishment/views/web.py b/apps/establishment/views/web.py index daa26d6a..53382be9 100644 --- a/apps/establishment/views/web.py +++ b/apps/establishment/views/web.py @@ -79,14 +79,6 @@ class EstablishmentCommentRUDView(generics.RetrieveUpdateDestroyAPIView): Returns the object the view is displaying. """ queryset = self.filter_queryset(self.get_queryset()) - lookup_url_kwargs = ('pk', 'comment_id') - - assert lookup_url_kwargs 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, pk=self.kwargs['pk']) @@ -107,14 +99,6 @@ class EstablishmentFavoritesCreateDestroyView(generics.CreateAPIView, generics.D """ Returns the object the view is displaying. """ - lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field - assert lookup_url_kwarg in self.kwargs, ( - '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_kwarg) - ) - obj = get_object_or_404( self.request.user.favorites.by_content_type(app_label='establishment', model='establishment') @@ -164,15 +148,6 @@ class EstablishmentScheduleRUDView(generics.RetrieveUpdateDestroyAPIView): """ Returns the object the view is displaying. """ - lookup_url_kwargs = ('pk', 'schedule_id') - - assert lookup_url_kwargs 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'] schedule_id = self.kwargs['schedule_id'] From 1e1b09660d9fd6f2071f0ee94d1b96b63332f9db Mon Sep 17 00:00:00 2001 From: Dmitriy Kuzmenko Date: Fri, 20 Sep 2019 15:55:37 +0300 Subject: [PATCH 6/6] fix news_type --- apps/establishment/tests.py | 8 +++++--- apps/search_indexes/documents/news.py | 8 ++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/apps/establishment/tests.py b/apps/establishment/tests.py index b64a971c..0aa44a0f 100644 --- a/apps/establishment/tests.py +++ b/apps/establishment/tests.py @@ -13,11 +13,13 @@ class BaseTestCase(APITestCase): self.password = 'sedragurdaredips19' self.email = 'sedragurda@desoz.com' 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 tokkens = User.create_jwt_tokens(self.user) - self.client.cookies = SimpleCookie({'access_token': tokkens.get('access_token'), - 'refresh_token': tokkens.get('refresh_token')}) + self.client.cookies = SimpleCookie( + {'access_token': tokkens.get('access_token'), + 'refresh_token': tokkens.get('refresh_token')}) class EmployeeTests(BaseTestCase): diff --git a/apps/search_indexes/documents/news.py b/apps/search_indexes/documents/news.py index bf67a0f6..45e50c42 100644 --- a/apps/search_indexes/documents/news.py +++ b/apps/search_indexes/documents/news.py @@ -46,3 +46,11 @@ class NewsDocument(Document): def prepare_description(self, instance): 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()