fixed problem with image, refactored favorites, collection

This commit is contained in:
Anatoly 2019-09-20 13:35:59 +03:00
parent 2a79018f76
commit 413c93bead
20 changed files with 166 additions and 123 deletions

View File

@ -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."""

View 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',
),
]

View 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'),
),
]

View File

@ -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."""

View File

@ -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:

View File

@ -7,11 +7,8 @@ app_name = 'collection'
urlpatterns = [
path('', views.CollectionListView.as_view(), name='list'),
path('<int:pk>/', views.CollectionRetrieveView.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('<int:pk>/establishments/', views.CollectionEstablishmentListView.as_view(),
name='detail'),
path('guides/', views.GuideListView.as_view(), name='guides-list'),
path('guides/<int:pk>/', views.GuideRetrieveView.as_view(), name='guides-detail'),

View File

@ -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

View File

@ -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'),
),
]

View 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 = [
]

View File

@ -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'),
),
]

View File

@ -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()

View File

@ -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',

View File

@ -16,5 +16,5 @@ urlpatterns = [
path('<int:pk>/comments/<int:comment_id>/', views.EstablishmentCommentRUDView.as_view(),
name='rud-comment'),
path('<int:pk>/favorites/', views.EstablishmentFavoritesCreateDestroyView.as_view(),
name='add-favorites')
name='add-to-favorites')
]

View File

@ -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.' %

View File

@ -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',
)

View File

@ -8,5 +8,4 @@ app_name = 'favorites'
urlpatterns = [
path('establishments/', views.FavoritesEstablishmentListView.as_view(),
name='establishment-list'),
path('remove/<int:pk>/', views.FavoritesDestroyView.as_view(), name='remove-from-favorites'),
]

View File

@ -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)

View File

@ -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):

View File

@ -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',
]

View File

@ -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: