gm-259, gm-260, gm-261
This commit is contained in:
parent
13eaa94261
commit
03c75efece
|
|
@ -241,6 +241,20 @@ class User(AbstractUser):
|
|||
template_name=settings.CHANGE_EMAIL_TEMPLATE,
|
||||
context=context)
|
||||
|
||||
@property
|
||||
def favorite_establishment_ids(self):
|
||||
"""Return establishment IDs that in favorites for current user."""
|
||||
return self.favorites.by_content_type(app_label='establishment',
|
||||
model='establishment')\
|
||||
.values_list('object_id', flat=True)
|
||||
|
||||
@property
|
||||
def favorite_recipe_ids(self):
|
||||
"""Return recipe IDs that in favorites for current user."""
|
||||
return self.favorites.by_content_type(app_label='recipe',
|
||||
model='recipe')\
|
||||
.values_list('object_id', flat=True)
|
||||
|
||||
|
||||
class UserRole(ProjectBaseMixin):
|
||||
"""UserRole model."""
|
||||
|
|
|
|||
|
|
@ -248,14 +248,12 @@ class EstablishmentQuerySet(models.QuerySet):
|
|||
|
||||
def annotate_in_favorites(self, user):
|
||||
"""Annotate flag in_favorites"""
|
||||
favorite_establishments = []
|
||||
favorite_establishment_ids = []
|
||||
if user.is_authenticated:
|
||||
favorite_establishments = user.favorites.by_content_type(app_label='establishment',
|
||||
model='establishment') \
|
||||
.values_list('object_id', flat=True)
|
||||
favorite_establishment_ids = user.favorite_establishment_ids
|
||||
return self.annotate(in_favorites=Case(
|
||||
When(
|
||||
id__in=favorite_establishments,
|
||||
id__in=favorite_establishment_ids,
|
||||
then=True),
|
||||
default=False,
|
||||
output_field=models.BooleanField(default=False)))
|
||||
|
|
|
|||
|
|
@ -5,15 +5,14 @@ from rest_framework import serializers
|
|||
from comment import models as comment_models
|
||||
from comment.serializers import common as comment_serializers
|
||||
from establishment import models
|
||||
from favorites.models import Favorites
|
||||
from location.serializers import AddressBaseSerializer
|
||||
from main.serializers import AwardSerializer, CurrencySerializer
|
||||
from review import models as review_models
|
||||
from tag.serializers import TagBaseSerializer
|
||||
from timetable.serialziers import ScheduleRUDSerializer
|
||||
from utils import exceptions as utils_exceptions
|
||||
from utils.serializers import ProjectModelSerializer
|
||||
from utils.serializers import TranslatedField
|
||||
from utils.serializers import (ProjectModelSerializer, TranslatedField,
|
||||
FavoritesCreateSerializer)
|
||||
|
||||
|
||||
class ContactPhonesSerializer(serializers.ModelSerializer):
|
||||
|
|
@ -281,26 +280,13 @@ class EstablishmentCommentRUDSerializer(comment_serializers.CommentSerializer):
|
|||
]
|
||||
|
||||
|
||||
class EstablishmentFavoritesCreateSerializer(serializers.ModelSerializer):
|
||||
"""Create comment serializer"""
|
||||
|
||||
class Meta:
|
||||
"""Serializer for model Comment"""
|
||||
model = Favorites
|
||||
fields = [
|
||||
'id',
|
||||
'created',
|
||||
]
|
||||
|
||||
def get_user(self):
|
||||
"""Get user from request"""
|
||||
return self.context.get('request').user
|
||||
class EstablishmentFavoritesCreateSerializer(FavoritesCreateSerializer):
|
||||
"""Serializer to favorite object w/ model Establishment."""
|
||||
|
||||
def validate(self, attrs):
|
||||
"""Override validate method"""
|
||||
"""Overridden validate method"""
|
||||
# Check establishment object
|
||||
establishment_slug = self.context.get('request').parser_context.get('kwargs').get('slug')
|
||||
establishment_qs = models.Establishment.objects.filter(slug=establishment_slug)
|
||||
establishment_qs = models.Establishment.objects.filter(slug=self.slug)
|
||||
|
||||
# Check establishment obj by slug from lookup_kwarg
|
||||
if not establishment_qs.exists():
|
||||
|
|
@ -309,18 +295,16 @@ class EstablishmentFavoritesCreateSerializer(serializers.ModelSerializer):
|
|||
establishment = establishment_qs.first()
|
||||
|
||||
# Check existence in favorites
|
||||
if self.get_user().favorites.by_content_type(app_label='establishment',
|
||||
model='establishment')\
|
||||
.by_object_id(object_id=establishment.id).exists():
|
||||
if establishment.favorites.filter(user=self.user).exists():
|
||||
raise utils_exceptions.FavoritesError()
|
||||
|
||||
attrs['establishment'] = establishment
|
||||
return attrs
|
||||
|
||||
def create(self, validated_data, *args, **kwargs):
|
||||
"""Override create method"""
|
||||
"""Overridden create method"""
|
||||
validated_data.update({
|
||||
'user': self.get_user(),
|
||||
'user': self.user,
|
||||
'content_object': validated_data.pop('establishment')
|
||||
})
|
||||
return super().create(validated_data)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ urlpatterns = [
|
|||
path('', views.EstablishmentListView.as_view(), name='list'),
|
||||
path('recent-reviews/', views.EstablishmentRecentReviewListView.as_view(),
|
||||
name='recent-reviews'),
|
||||
# path('wineries/', views.WineriesListView.as_view(), name='wineries-list'),
|
||||
path('slug/<slug:slug>/', views.EstablishmentRetrieveView.as_view(), name='detail'),
|
||||
path('slug/<slug:slug>/similar/', views.EstablishmentSimilarListView.as_view(), name='similar'),
|
||||
path('slug/<slug:slug>/comments/', views.EstablishmentCommentListView.as_view(), name='list-comments'),
|
||||
|
|
@ -18,5 +17,5 @@ urlpatterns = [
|
|||
path('slug/<slug:slug>/comments/<int:comment_id>/', views.EstablishmentCommentRUDView.as_view(),
|
||||
name='rud-comment'),
|
||||
path('slug/<slug:slug>/favorites/', views.EstablishmentFavoritesCreateDestroyView.as_view(),
|
||||
name='add-to-favorites')
|
||||
name='create-destroy-favorites')
|
||||
]
|
||||
|
|
|
|||
|
|
@ -138,15 +138,12 @@ class EstablishmentFavoritesCreateDestroyView(generics.CreateAPIView, generics.D
|
|||
"""
|
||||
Returns the object the view is displaying.
|
||||
"""
|
||||
establishment_obj = get_object_or_404(models.Establishment,
|
||||
slug=self.kwargs['slug'])
|
||||
obj = get_object_or_404(
|
||||
self.request.user.favorites.by_content_type(app_label='establishment',
|
||||
model='establishment')
|
||||
.by_object_id(object_id=establishment_obj.pk))
|
||||
establishment = get_object_or_404(models.Establishment,
|
||||
slug=self.kwargs['slug'])
|
||||
favorites = get_object_or_404(establishment.favorites.filter(user=self.request.user))
|
||||
# May raise a permission denied
|
||||
self.check_object_permissions(self.request, obj)
|
||||
return obj
|
||||
self.check_object_permissions(self.request, favorites)
|
||||
return favorites
|
||||
|
||||
|
||||
class EstablishmentNearestRetrieveView(EstablishmentListView, generics.ListAPIView):
|
||||
|
|
@ -170,14 +167,3 @@ class EstablishmentNearestRetrieveView(EstablishmentListView, generics.ListAPIVi
|
|||
return qs.by_distance_from_point(**{k: v for k, v in filter_kwargs.items()
|
||||
if v is not None})
|
||||
return qs
|
||||
|
||||
|
||||
# Wineries
|
||||
# todo: find out about difference between subtypes data
|
||||
# class WineriesListView(EstablishmentListView):
|
||||
# """Return list establishments with type Wineries"""
|
||||
#
|
||||
# def get_queryset(self):
|
||||
# """Overridden get_queryset method."""
|
||||
# qs = super(WineriesListView, self).get_queryset()
|
||||
# return qs.with_type_related().wineries()
|
||||
|
|
|
|||
|
|
@ -8,4 +8,6 @@ app_name = 'favorites'
|
|||
urlpatterns = [
|
||||
path('establishments/', views.FavoritesEstablishmentListView.as_view(),
|
||||
name='establishment-list'),
|
||||
path('products/', views.FavoritesProductListView.as_view(),
|
||||
name='product-list'),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ from rest_framework import generics
|
|||
from establishment.models import Establishment
|
||||
from establishment.filters import EstablishmentFilter
|
||||
from establishment.serializers import EstablishmentBaseSerializer
|
||||
from product.models import Product
|
||||
from product.serializers import ProductBaseSerializer
|
||||
from product.filters import ProductFilterSet
|
||||
from .models import Favorites
|
||||
|
||||
|
||||
|
|
@ -15,7 +18,7 @@ class FavoritesBaseView(generics.GenericAPIView):
|
|||
|
||||
|
||||
class FavoritesEstablishmentListView(generics.ListAPIView):
|
||||
"""List views for favorites"""
|
||||
"""List views for establishments in favorites."""
|
||||
|
||||
serializer_class = EstablishmentBaseSerializer
|
||||
filter_class = EstablishmentFilter
|
||||
|
|
@ -24,3 +27,15 @@ class FavoritesEstablishmentListView(generics.ListAPIView):
|
|||
"""Override get_queryset method"""
|
||||
return Establishment.objects.filter(favorites__user=self.request.user)\
|
||||
.order_by('-favorites')
|
||||
|
||||
|
||||
class FavoritesProductListView(generics.ListAPIView):
|
||||
"""List views for products in favorites."""
|
||||
|
||||
serializer_class = ProductBaseSerializer
|
||||
filter_class = ProductFilterSet
|
||||
|
||||
def get_queryset(self):
|
||||
"""Override get_queryset method"""
|
||||
return Product.objects.filter(favorites__user=self.request.user)\
|
||||
.order_by('-favorites')
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from django_filters import rest_framework as filters
|
|||
from product import models
|
||||
|
||||
|
||||
class ProductListFilterSet(filters.FilterSet):
|
||||
class ProductFilterSet(filters.FilterSet):
|
||||
"""Product filter set."""
|
||||
|
||||
establishment_id = filters.NumberFilter()
|
||||
|
|
|
|||
18
apps/product/migrations/0002_product_slug.py
Normal file
18
apps/product/migrations/0002_product_slug.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 2.2.4 on 2019-10-29 14:07
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('product', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='product',
|
||||
name='slug',
|
||||
field=models.SlugField(max_length=255, null=True, unique=True, verbose_name='Establishment slug'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
"""Product app models."""
|
||||
from django.db import models
|
||||
from django.contrib.contenttypes import fields as generic
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.contrib.postgres.fields import JSONField
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
|
@ -141,6 +142,9 @@ class Product(TranslatedFieldsMixin, BaseAttributes):
|
|||
wine_appellation = models.ForeignKey('location.WineAppellation', on_delete=models.PROTECT,
|
||||
blank=True, null=True,
|
||||
verbose_name=_('wine appellation'))
|
||||
slug = models.SlugField(unique=True, max_length=255, null=True,
|
||||
verbose_name=_('Establishment slug'))
|
||||
favorites = generic.GenericRelation(to='favorites.Favorites')
|
||||
|
||||
objects = ProductManager.from_queryset(ProductQuerySet)()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
"""Product app serializers."""
|
||||
from rest_framework import serializers
|
||||
from utils.serializers import TranslatedField
|
||||
from utils.serializers import TranslatedField, FavoritesCreateSerializer
|
||||
from product.models import Product, ProductSubType, ProductType
|
||||
from utils import exceptions as utils_exceptions
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from location.serializers import (WineRegionBaseSerializer, WineAppellationBaseSerializer,
|
||||
CountrySimpleSerializer)
|
||||
CountrySimpleSerializer)
|
||||
|
||||
|
||||
class ProductSubTypeBaseSerializer(serializers.ModelSerializer):
|
||||
|
|
@ -50,6 +52,7 @@ class ProductBaseSerializer(serializers.ModelSerializer):
|
|||
model = Product
|
||||
fields = [
|
||||
'id',
|
||||
'slug',
|
||||
'name_translated',
|
||||
'category_display',
|
||||
'description_translated',
|
||||
|
|
@ -61,3 +64,33 @@ class ProductBaseSerializer(serializers.ModelSerializer):
|
|||
'wine_appellation',
|
||||
'available_countries',
|
||||
]
|
||||
|
||||
|
||||
class ProductFavoritesCreateSerializer(FavoritesCreateSerializer):
|
||||
"""Serializer to create favorite object w/ model Product."""
|
||||
|
||||
def validate(self, attrs):
|
||||
"""Overridden validate method"""
|
||||
# Check establishment object
|
||||
product_qs = Product.objects.filter(slug=self.slug)
|
||||
|
||||
# Check establishment obj by slug from lookup_kwarg
|
||||
if not product_qs.exists():
|
||||
raise serializers.ValidationError({'detail': _('Object not found.')})
|
||||
else:
|
||||
product = product_qs.first()
|
||||
|
||||
# Check existence in favorites
|
||||
if product.favorites.filter(user=self.user).exists():
|
||||
raise utils_exceptions.FavoritesError()
|
||||
|
||||
attrs['product'] = product
|
||||
return attrs
|
||||
|
||||
def create(self, validated_data, *args, **kwargs):
|
||||
"""Overridden create method"""
|
||||
validated_data.update({
|
||||
'user': self.user,
|
||||
'content_object': validated_data.pop('product')
|
||||
})
|
||||
return super().create(validated_data)
|
||||
|
|
@ -6,5 +6,7 @@ from product import views
|
|||
app_name = 'product'
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.ProductListView.as_view(), name='list')
|
||||
path('', views.ProductListView.as_view(), name='list'),
|
||||
path('slug/<slug:slug>/favorites/', views.CreateFavoriteProductView.as_view(),
|
||||
name='create-destroy-favorites')
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""Product app views."""
|
||||
from rest_framework import generics, permissions
|
||||
from django.shortcuts import get_object_or_404
|
||||
from product.models import Product
|
||||
from product import serializers
|
||||
from product import filters
|
||||
|
|
@ -17,4 +18,22 @@ class ProductListView(ProductBaseView, generics.ListAPIView):
|
|||
"""List view for model Product."""
|
||||
permission_classes = (permissions.AllowAny, )
|
||||
serializer_class = serializers.ProductBaseSerializer
|
||||
filter_class = filters.ProductListFilterSet
|
||||
filter_class = filters.ProductFilterSet
|
||||
|
||||
|
||||
class CreateFavoriteProductView(generics.CreateAPIView,
|
||||
generics.DestroyAPIView):
|
||||
"""View for create/destroy product in favorites."""
|
||||
serializer_class = serializers.ProductFavoritesCreateSerializer
|
||||
lookup_field = 'slug'
|
||||
|
||||
def get_object(self):
|
||||
"""
|
||||
Returns the object the view is displaying.
|
||||
"""
|
||||
product = get_object_or_404(Product, slug=self.kwargs['slug'])
|
||||
favorites = get_object_or_404(product.favorites.filter(user=self.request.user))
|
||||
|
||||
# May raise a permission denied
|
||||
self.check_object_permissions(self.request, favorites)
|
||||
return favorites
|
||||
|
|
|
|||
|
|
@ -15,14 +15,12 @@ class RecipeQuerySet(models.QuerySet):
|
|||
|
||||
def annotate_in_favorites(self, user):
|
||||
"""Annotate flag in_favorites"""
|
||||
favorite_establishments = []
|
||||
favorite_recipe_ids = []
|
||||
if user.is_authenticated:
|
||||
favorite_establishments = user.favorites.by_content_type(app_label='recipe',
|
||||
model='recipe') \
|
||||
.values_list('object_id', flat=True)
|
||||
favorite_recipe_ids = user.favorite_recipe_ids
|
||||
return self.annotate(in_favorites=models.Case(
|
||||
models.When(
|
||||
id__in=favorite_establishments,
|
||||
id__in=favorite_recipe_ids,
|
||||
then=True),
|
||||
default=False,
|
||||
output_field=models.BooleanField(default=False)))
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from django.core import exceptions
|
|||
from rest_framework import serializers
|
||||
from utils import models
|
||||
from translation.models import Language
|
||||
from favorites.models import Favorites
|
||||
|
||||
|
||||
class EmptySerializer(serializers.Serializer):
|
||||
|
|
@ -72,3 +73,28 @@ class ProjectModelSerializer(serializers.ModelSerializer):
|
|||
"""Overrided ModelSerializer."""
|
||||
|
||||
serializers.ModelSerializer.serializer_field_mapping[models.TJSONField] = TJSONField
|
||||
|
||||
|
||||
class FavoritesCreateSerializer(serializers.ModelSerializer):
|
||||
"""Serializer to favorite object."""
|
||||
|
||||
class Meta:
|
||||
"""Serializer for model Comment."""
|
||||
model = Favorites
|
||||
fields = [
|
||||
'id',
|
||||
'created',
|
||||
]
|
||||
|
||||
@property
|
||||
def request(self):
|
||||
return self.context.get('request')
|
||||
|
||||
@property
|
||||
def user(self):
|
||||
"""Get user from request"""
|
||||
return self.request.user
|
||||
|
||||
@property
|
||||
def slug(self):
|
||||
return self.request.parser_context.get('kwargs').get('slug')
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user